Reputation: 19770
This is a simplified example of a complex code:
type ValueType<T> = [T] extends [string] ? Value<string> : Value<T>;
interface Value<T> {
set(v: T): void
}
export type Bar<T> = T extends true ? boolean : number
function foo<T>(vt: ValueType<Bar<T>>, v: Bar<T>) {
vt.set(v); <-- error here
}
The latest TypeScript (v4.1.3) fails on the statement vt.set(v)
with:
Argument of type 'Bar' is not assignable to parameter of type 'string & Bar'.
Is this behavior documented somewhere or is it a bug?
Upvotes: 0
Views: 151
Reputation: 276239
Here is the error you are getting:
Argument of type 'Bar<T>' is not assignable to parameter of type 'string & Bar<T>'.
Type 'number | boolean' is not assignable to type 'string & Bar<T>'. Type 'number' is not assignable to type 'string & Bar<T>'.
Type 'number' is not assignable to type 'string'.
Type 'Bar<T>' is not assignable to type 'string'. Type 'number | boolean' is not assignable to type 'string'.
So the root cause is Type 'Bar<T>' is not assignable to type 'string'. Type 'number | boolean' is not assignable to type 'string'.
and it makes perfect sense to have this error and we explain this below
Based on export type Bar<T> = T extends true ? boolean : number
boolean
or number
Based on type ValueType<T> = [T] extends [string] ? Value<string> : Value<T>;
ValueType
can be Value<string>
Based on foo<T>(vt: ValueType<Bar<T>>, v: Bar<T>)
means vt.set can take string
Based on Fact 1 (can only be boolean
or number
) and Fact 2 (can take a string
) we have the error message from TypeScript: Type 'number | boolean' is not assignable to type 'string'
Upvotes: 1