如何推断扩展泛型类型的子 属性 类型?
How can I infer the child property types of an extended Generic type?
我想编写一个 return 是 属性 扩展泛型类型的函数。有可能吗?
这是我尝试过的方法:
interface Animal {
readonly weight: {total: number}
}
interface Dog extends Animal {
readonly weight: {total: number, tail: number, head: number, body: number }
}
const getWeight = <T extends Animal>(animal: T) => {
return animal.weight
}
const myDog = { weight: { total: 20, tail: 5, head: 5, body: 10 } }
const myDogsWeight = getWeight<Dog>(myDog)
// Property 'head' does not exist on type '{ total: number; }'.
const myDogsHeadWeight = myDogsWeight.head
如果我尝试显式注释函数的 return 类型,我会得到另一个错误:
type InferredWeight<TAnimal> = TAnimal extends { readonly weight: infer U } ? U : never
type DogWeight = InferredWeight<Dog> // <-- This type works correctly
const getWeightTyped = <T extends Animal>(animal: T): InferredWeight<T> => {
// Type '{ total: number; }' is not assignable to type 'InferredWeight<T>'.
return animal.weight
}
这是 playground link.
唯一似乎相关的 TypeScript Github 问题是 this one,但它是联合类型的问题。
如@jcalz 的评论中所述,您可以使用查找类型:
这应该能满足您的需求。
interface Animal {
readonly weight: { total: number }
}
interface Dog extends Animal {
readonly weight: { total: number, tail: number, head: number, body: number }
}
const getWeight = <
T extends Animal
>(animal: T): T['weight'] => {
return animal.weight
}
const myDog = { weight: { total: 20, tail: 5, head: 5, body: 10 } }
const myDogsWeight = getWeight(myDog);
我想编写一个 return 是 属性 扩展泛型类型的函数。有可能吗?
这是我尝试过的方法:
interface Animal {
readonly weight: {total: number}
}
interface Dog extends Animal {
readonly weight: {total: number, tail: number, head: number, body: number }
}
const getWeight = <T extends Animal>(animal: T) => {
return animal.weight
}
const myDog = { weight: { total: 20, tail: 5, head: 5, body: 10 } }
const myDogsWeight = getWeight<Dog>(myDog)
// Property 'head' does not exist on type '{ total: number; }'.
const myDogsHeadWeight = myDogsWeight.head
如果我尝试显式注释函数的 return 类型,我会得到另一个错误:
type InferredWeight<TAnimal> = TAnimal extends { readonly weight: infer U } ? U : never
type DogWeight = InferredWeight<Dog> // <-- This type works correctly
const getWeightTyped = <T extends Animal>(animal: T): InferredWeight<T> => {
// Type '{ total: number; }' is not assignable to type 'InferredWeight<T>'.
return animal.weight
}
这是 playground link.
唯一似乎相关的 TypeScript Github 问题是 this one,但它是联合类型的问题。
如@jcalz 的评论中所述,您可以使用查找类型:
这应该能满足您的需求。
interface Animal {
readonly weight: { total: number }
}
interface Dog extends Animal {
readonly weight: { total: number, tail: number, head: number, body: number }
}
const getWeight = <
T extends Animal
>(animal: T): T['weight'] => {
return animal.weight
}
const myDog = { weight: { total: 20, tail: 5, head: 5, body: 10 } }
const myDogsWeight = getWeight(myDog);