我想定义一个具有条件返回类型的类型脚本函数,该类型取决于参数的类型:用true类型的参数调用,它返回一个字符串,用False类型的参数调用,它返回一个数字.我想出了以下函数foo(),它几乎按预期工作:
- 用true调用它,就会推断出正确的返回类型(字符串)
- 将其称为"假",则推断出正确的返回类型(数字)
但当直接将函数调用分配给不兼容的类型时,不会引发类型错误,为什么呢?
// generic function with conditional return-type TReturn that depends on TSomeArg
const foo = <
TSomeArg extends boolean,
TReturn = TSomeArg extends true ? string : number,
>(
someArg: TSomeArg,
): TReturn => {
// to return the conditional type TReturn, one needs to explictly assert it, since typescript will otherwise infer the union type: 'Some String'|1234
return (someArg ? "Some String" : 1234) as unknown as TReturn;
};
// this works fine
const testOne = foo(true); // inferred string as expected: "const testOne: string"
// ^?
const testTwo = foo(false); // inferred number as expected: "const testTwo: number"
// ^?
const testThree: number = testOne; // throws Error as expected: "Type 'string' is not assignable to type 'number'."
const testFour: string = testTwo; // throws Error as expected: "Type 'number' is not assignable to type 'string'."
// BUT, here I would expect some type-errors
const testFive: number = foo(true); // unexpected: no type-error (string is inccorrectly accepted as a number)
const testSix: string = foo(false); // unexpected: no type-error (number is incorrectly accepted as a string)
// only when I explicitly define TSomeArg, then the type-errors are thrown as expected
const testSeven: number = foo<true>(true); // throws type-error as expected: "Type 'string' is not assignable to type 'number'."
const testEighth: string = foo<false>(false); // throws type-error as expected: "Type 'number' is not assignable to type 'string'."
相同代码为ts-playground