Typescript 条件类型的可选参数

Typescript 条件类型的可选参数,typescript,types,Typescript,Types,我偶然发现了一个我完全不懂的问题。我找到了类似问题的答案,但没有任何帮助我理解这一点 我有以下功能: const one = <T extends boolean>(param?: T): T extends true ? string : number => { return (param ? '1' : 1) as T extends true ? string : number; } const foo = one(true); // type string con

我偶然发现了一个我完全不懂的问题。我找到了类似问题的答案,但没有任何帮助我理解这一点

我有以下功能:

const one = <T extends boolean>(param?: T): T extends true ? string : number => {
  return (param ? '1' : 1) as T extends true ? string : number;
}

const foo = one(true); // type string
const bar = one(false); // type number
const baz = one(); // type string | number

我不是100%确定为什么,但我有预感

编译器认为它没有足够的信息来决定条件的哪个分支,所以它放弃了,并说它可能是其中之一。你可能认为
T
显然是
boolean | undefined
的一个子类型,但你也说过
T
是一个布尔值,不能未定义

当省略参数
params?:T
没有允许其推断
T
的类型。这类似于此条件类型:

type A = any extends true ? 1 : 2 // 1 | 2
因此,当在条件中使用
T
时,编译器不知道它可能是什么,因此它将其视为
any
,并返回条件的两侧

我认为最简单的修复方法是为
T
提供一个默认类型,在省略参数时将使用该类型

const one = <T extends boolean = false>(param?: T): T extends true ? string : number => {
  return (param ? '1' : 1) as T extends true ? string : number;
}

const baz = one(); // type number
const one=(参数?:T):T扩展为真?字符串:number=>{
当T扩展为true时返回(参数?:1)?字符串:number;
}
常数baz=one();//型号

我同意编译器应该能够计算出
T
这里是
boolean | undefined
,这并不能扩展
true
,但它并不完美。添加默认类型可以消除很多混淆


如果这里的typescript存在问题,那就是它允许您从可选参数推断
T
,而不使用默认值,这会产生意外结果,因为
T
不是您在这种情况下真正可以使用的类型。

非常感谢您的详细解释!这让我有点烦,但现在我明白了。默认值是整洁的解决方案
const one = <T extends boolean = false>(param?: T): T extends true ? string : number => {
  return (param ? '1' : 1) as T extends true ? string : number;
}

const baz = one(); // type number