-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Generic type param not narrowed in true branch of conditional type #42077
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
Comments
Currently narrowing doesn't apply to constraints; I'm not sure how feasible that would be. Simpler example type NumberIfOne<T> = T extends number ? 1 : 0;
type OneOnly<T extends 1> = T;
// Error, but should be OK (?)
type S<T, U extends NumberIfOne<T>> = T extends number ? OneOnly<U> : false; |
It seems that this example illustrates the same point. It was unclear to me why function test1(input: boolean) {
if (input === true) {
throw new Error("!")
}
needsFalse(input) // OK, expected
}
function test2<T extends boolean>(input: T) {
if (input === true) {
throw new Error("!")
}
needsFalse(input)
/**
* Argument of type 'T' is not assignable to parameter of type 'false'.
* Type 'boolean' is not assignable to type 'false'.(2345)
*/
}
declare function needsFalse(input: false): void I need a generic there to eventually write a conditional return type based on the function parameter. |
Is this a similar case? type ValueType<T> = [T] extends [string] ? Value<string> : Value<T>;
interface Value<T> {
set(v: T): void
}
export type Foo1<T> = T extends true ? boolean : number
function foo1<T>(vt: ValueType<Foo1<T>>, v: Foo1<T>) {
vt.set(v); // <-- error here
}
export type Foo2<T> = T | undefined
function foo2<T>(vt: ValueType<Foo2<T>>, v: Foo2<T>) {
vt.set(v); // <-- error here
}
export type Foo3<T> = T & { bar: boolean }
function foo3<T>(vt: ValueType<Foo3<T>>, v: Foo3<T>) {
vt.set(v); // <-- error here
} Or it fails for a different reason? |
this is still giving my example an error after 4.3.0-beta, but agentcooper's example compiles now. I'm guessing it's because he's using a type guard where I'm using a conditional type. |
Is this a similar case? (Playground) type Variables = { [x: string]: unknown };
type Foo<T extends Variables> = T extends Record<any, never>
? "true"
: "false";
function func<T extends Variables>() {
const f: Foo<T & { endCursor: any }> = "false"; // ts(2322): Type '"false"' is not assignable to type 'Foo<T & { endCursor: any; }>'
const t: Foo<T & { endCursor: any }> = "true"; // ts(2322): Type '"true"' is not assignable to type 'Foo<T & { endCursor: any; }>'
} |
TypeScript Version: 4.1.2
Search Terms: conditional type true branch generic narrowing
Code
Expected behavior: in
CommandData
we are narrowing the generic parameterU
using a conditional type, so in the true branch of the conditionalC
should also be "narrowed" (not sure if that's the correct term in this case) to the specific command type that depends on U.Actual behavior: the compiler says that in the true branches of
CommandData
conditionals, C does not satisfy the constraint of eitherNumCommandData
orChrCommandData
Playground Link: playground
Related Issues: maybe #24085 ?
The text was updated successfully, but these errors were encountered: