Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Omit properties from generic type which set by default and have extend #33484

Closed
Vardner opened this issue Sep 18, 2019 · 7 comments
Closed

Omit properties from generic type which set by default and have extend #33484

Vardner opened this issue Sep 18, 2019 · 7 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@Vardner
Copy link

Vardner commented Sep 18, 2019

TypeScript Version: 3.6.3
Omit extended generic type, type has no properties in common with type Pick Exclude

interface Bar {
    type: string;
    id?: string;
}

class Foo\<T extends Bar = Bar> {
    getParam (param: keyof Omit<T, 'type'>) {}

    test () {
        this.getParam('id');
    }
}

Expected behavior:
exclude the "type" property, and get in the available properties for the parameter "param" id and the rest that will be present in the interface because Bar is default param for T

Actual behavior:
Error "Type 'type' has no properties in common with type Pick <T, Exclude , 'type'>"

Playground Link:
https://stackblitz.com/edit/typescript-8zyjig

Related Issues: #24791

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Sep 18, 2019
@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Sep 18, 2019

Operations like keyof Omit are higher-order and can't be related to concrete types like "id". From inspection we (humans) can say that "id" should be assignable to that type, but there's no way for TS to represent keyof Omit<T, 'type'>'s type in this format in order to answer that question.

@Vardner
Copy link
Author

Vardner commented Sep 18, 2019

@RyanCavanaugh Maybe you should indicate this in the documentation so as not to mislead beginners like me? I expected that TypeScript would understand that a universal type expanding by a certain interface would be able to get keys from it. Expected behavior was that omit will get all keys from Bar because T is extending him

@Vardner
Copy link
Author

Vardner commented Sep 18, 2019

@RyanCavanaugh I just want to note that if you extend a given class with a subclass of some kind and pass in a prepared object that is expanded by the Bar interface, then it begins to understand which keys need to be sorted out. That is, this problem can be fixed with a crutch by increasing the chain of inheritance by 1. You can see that in file index2.ts https://stackblitz.com/edit/typescript-8zyjig

@RyanCavanaugh
Copy link
Member

Which documentation pages had you referred to before logging this? I'm trying to figure out which one to potentially add the information to.

@Vardner
Copy link
Author

Vardner commented Sep 18, 2019

@vipcxj
Copy link

vipcxj commented Sep 20, 2019

@RyanCavanaugh what does high-order mean?
why TS know how to deal with keyof Omit<Bar, 'type'>
playground
Is there some limits on generic type or Omit?

@mykwillis
Copy link

Something seems a little fishy here, because it seems TypeScript is able to properly build a list of a generic type's properties with keyof (i.e., if that generic type is specified to extend from another type), but it is not able to do the same thing with Exclude. It wouldn't seem (to an outsider) that these should be different problems.

See for example this example from https://stackoverflow.com/questions/64920228/using-typescript-exclude-with-generic-type

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

4 participants