我试图根据参数从泛型函数返回映射类型的值,该类型似乎在调用时被正确检测到,但在返回时报告错误。
我不考虑在 genericFunction
上使用重载,因为 E
在我的用例中可能有超过 100 个值。
enum E {
e1="e1",
e2="e2"
}
interface E1Payload {
payloadFrom1: string
anotherField: number
}
interface E2Payload {
payloadFrom2: string
}
type Mapping = {
[E.e1]: E1Payload
[E.e2]: E2Payload
}
function genericFunction<K extends keyof Mapping>(e: K): Mapping[K] {
if (e === E.e1) {
// ERROR: Type '{ payloadFrom1: string; anotherField: number; }' is not assignable to type 'Mapping[K]'.
// Type '{ payloadFrom1: string; anotherField: number; }' is not assignable to type 'E1Payload & E2Payload'.
// Property 'payloadFrom2' is missing in type '{ payloadFrom1: string; anotherField: number; }' but required in type 'E2Payload'.
return {
payloadFrom1: "e1",
anotherField: 2
}
}
// ERROR: Type '{ payloadFrom2: string; }' is not assignable to type 'Mapping[K]'.
// Type '{ payloadFrom2: string; }' is not assignable to type 'E1Payload & E2Payload'.
// Type '{ payloadFrom2: string; }' is missing the following properties from type 'E1Payload': payloadFrom1, anotherField
return {
payloadFrom2: "e2"
}
}
// This work correctly
const payloadE1: E1Payload = genericFunction(E.e1)
const payloadE2: E2Payload = genericFunction(E.e2)
最佳答案
您可以通过重写 genericFunction
以包含类似 map 的结构来解决此问题:
function genericFunction<K extends keyof Mapping>(e: K): Mapping[K] {
return {
[E.e1]: {
payloadFrom1: "e1",
anotherField: 2
},
[E.e2]: {
payloadFrom2: "e2"
}
}[e]
}
对于更复杂的场景,我建议使用类型断言。 TypeScript 无法真正缩小泛型类型的范围。这就是为什么它无法理解您在这里所做的 if/else
缩小范围。
关于typescript - 根据参数从映射类型返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72969897/