-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Case for inference failure in T extends F<T>
#51377
Comments
In TypeScript, generics usually work just fine, however when you start using already extended generic types to define new generic types that will also be extended - this is where the trouble occurs. In general, Generic Constraints (e.g. ) in TypeScript are not considered as types that can be inferred further, meaning that whilst extending an extended type like you have in f4 is harmless, extending a newly defined type that also uses generics is problematic: f4 is perfectly fine: <Type1 extends Type2, Type2 extends OrderType> f3 is also fine as it is not extending the type to define the callback but is instead creating directly: f: (t: Type) => Promise f2 is where the problem begins to occur as the parameter type is using an extended generic type that also uses extended values. This causes the type to default itself back to OrderType and because FullType does not directly equal OrderType you are observing that error: Fn extends (t: Type) => Promise |
Btw one can write a class equivalent of this too... interface F
{ a: unknown
, b: (a: this["a"]) => unknown
}
new class implements F {
a = "hello"
b = x => x.toUpperCase()
}
// doesn't compile because `x` is inferred as `any` instead of `string`.
new class implements F {
a = "hello"
b = (x: string) => x.toUpperCase()
}
// compiles |
@RyanCavanaugh Could I use this thread to ask some quick trivial questions about the codebase? I'm giving a silly shot at writing a PR for this. The question I have right now is how do you create a type from a type alias symbol and a type passed in as an argument? I imagine something like this...? let yType = createType(0) // What flags to pass in?
yType.aliasSymbol = fSymbol
yType.aliasArguments = [xType]
Also let me know if there's a better place/way to ask questions like this. Edit: I don't need the answer anymore turns out I didn't exactly needed it (see #51511), but still I'd be bonus if I get to know the answer anyway :P Edit 2: Ah I think |
This would be helpful for excluding certain types in a generic type Example: type Optional<T extends NonNullable<T>> =
| { kind: 'Some'; value: T; }
| { kind: 'None'; };
type OptionalNull = Optional<null>;
// ^^^^
// Error: Type 'null' does not satisfy the constraint 'NonNullable<null>'.
// Because type 'null' does not satisfy the constraint 'never'.
type OptionalNull = Optional<null | string>;
// ^^^^^^^^^^^^^
// Error: Type 'null | string' does not satisfy the constraint 'NonNullable<null | string>'.
// Because type 'null' does not satisfy the constraint 'string'. |
Your comment/usecase belongs to #51011. This issue is for this specific inference failure in the OP, and here |
Bug Report
π Search Terms
circular type parameter constraint
Related issues: #40439 #30134
π Version & Regression Information
Tested with 4.8.4
β― Playground Link
Playground
π» Code
Note that there is a workaround but it's only a workaround for this minimal case and not for the real world case from which this minimal case was derived.
π Actual behavior
x
in the firstf
call gets inferred asunknown
π Expected behavior
x
in the firstf
call should get inferred asstring
The text was updated successfully, but these errors were encountered: