我正在尝试创建一个泛型函数,该函数根据其参数的类型有条件地返回值,但是我一直在尝试实现返回类型。
假设类型为 USA USA USA USA UK UK
Date Alabama Alaska Kansas Maryland London Edinburgh
-----------------------------------------------------------------------
01/01/2019 1 2 3 4 5 6
02/01/2019 7 8 9 10 11 12
03/01/2019 13 14 15 16 17 18
Basket
现在,如果我想根据传递给函数的参数有条件地返回“ banana”或“ tomato”,则无法编译它:
type Basket = {
Fruit: 'banana',
Veggie: 'tomato'
}
现在,当我在传递正确的通用参数后实例化此参数时,我得到了我所期望的类型,但是它无法编译
const f1 = <T extends keyof Basket>(t: T): T extends 'Fruit'? 'banana': 'tomato' => {
if (t == 'Fruit') {
return 'banana' //Error on this line - doesn't compile -- Type '"banana"' is not assignable to type '"banana" & "tomato"
} else {
return 'tomato' //Error on this line - doesn't compile -- Type '"tomato"' is not assignable to type '"banana" & "tomato"
}
}
但是,如果我不使用泛型,我会得到一个像这样的求和类型
const doesntCompile: 'banana' = f1<'Fruit'>('') //type: 'banana', which is what I want ... but this doesn't compile due to the error above.
现在它可以正常编译,但是我失去了类型安全性的好处。
如何在保留泛型的同时使该示例正常工作?任何帮助深表感谢。
答案 0 :(得分:2)
关于您的问题,它来自延迟的条件类型。查看打字稿文档:https://www.typescriptlang.org/docs/handbook/advanced-types.html#conditional-types。 (将条件类型的搜索推迟到页面中的正确位置。)
最简单的解决方案是使用一个更宽松的单独实现签名,同时将公共签名保留为对调用者更有利的条件类型:
type Basket = {
Fruit: 'banana',
Veggie: 'tomato'
}
function f3 <T extends keyof Basket>(t: T): Basket[T];
function f3 <T extends keyof Basket>(t: string): Basket[keyof Basket] {
if (t == 'Fruit') {
return 'banana'
} else {
return 'tomato'
}
}
const complies2 = f3('Fruit'); // complies2 is "banana"
注意:箭头函数不适用于函数重载。