以下功能已从typescript handbook section on using conditional types取消,但不起作用:
function test<T extends boolean>(a: T): T extends true ? string : number {
return a ? '1' : 1
}
打字稿报告:
Type '1 | "1"' is not assignable to type 'T extends true ? string : number'.
Type '1' is not assignable to type 'T extends true ? string : number'.
我想我缺少明显的东西。如何构造该函数,以便打字稿根据函数的参数正确推断出类型?
我意识到可以使用函数签名重载来解决此特定问题,但我想了解更多有关条件类型的信息。
答案 0 :(得分:2)
一个简短的答案是你不能。没有值将无法分配给未解析的条件类型(条件类型仍然取决于自由的泛型类型变量)。您唯一可以做的就是使用类型断言。
function test<T extends boolean>(a: T): T extends true ? string : number {
return (a ? '1' : 1) as any
}
条件类型对于表达参数之间的关系很有用,但是在实现函数时却无济于事。另一种方法是使用更宽松的实现签名。
function test<T extends boolean>(a: T): T extends true ? string : number
function test(a: boolean): number | string {
return (a ? '1' : 1)
}
答案 1 :(得分:2)
TypeScript可以正确推断返回类型。它不做的是不检查运行时逻辑是否遵循条件类型中指定的条件,在您的情况下,它会导致编译时错误。您可以通过使用索引类型访问来根据条件获取所需的类型,从而避免错误。
与您在问题中声明的test
相比,它将具有不同的行为,即,如果在编译时类型未知,它将推断联合类型。仍将不检查实现是否符合条件类型逻辑,但是没有错误,也没有类型断言:
interface Selector {
t: string;
f: number;
}
function test<T extends boolean>(a: T): Selector[T extends true ? 't' : 'f'] {
// NOTE: not checked that is returns correct type actually
return a ? '1' : 1
}
const t1 = test(true); // string
const t2 = test(false); // number
declare var b: boolean;
const t3 = test(b); // string | number, which may or may not be what you want