【发布时间】:2020-06-28 11:07:06
【问题描述】:
在下面的打字稿示例中,我有一个函数getPerson,它只需要一个对象和一个键来查找值。但是输入对象是部分泛型:
export type Person = {
name: string;
age: string;
}
export type People = Record<string, Person>;
function getPerson<D extends People>(partialData: Partial<D>, key: string): Person {
if (!partialData.hasOwnProperty(key)) {
throw new Error("key not found in dataContainer.incompleteDataSet");
}
return partialData[key]; // TS Lint Error here
}
此代码似乎可以按我的意愿工作,但是我在 return 语句中收到 TS Lint 错误:
TS2322: Type 'D[string] | undefined' is not assignable to type 'Person'.
Type 'undefined' is not assignable to type 'Person
在函数getPerson 中,Generic D 应该指定我们拥有什么样的People,例如D 可以是带有 mom 和 dad 键的 Parents 类型。
export type Parents = {
mom: Person,
dad: Person,
}
const parentsData: Partial<Parents> = {
mom: {
name: "Ann",
age: "55",
}
}
const mom: Person = getPerson(parentsData, "mom");
console.log(mom);
但是getPerson 也应该开放以与其他人结构一起使用,如下所示:
const grandParentsData: Partial<Grandparents> = getGrandParentsData();
const grandma: Person = getPerson(grandParentsData, "grandma");
我发现表达这一点的最佳方式是 <D extends People> 旁边的 getPerson。不过,这可能会导致我的 linting 问题,因为D 将被允许拥有其他键值,而不仅仅是<string, Person> 中定义的People。我对吗?您有什么想法可以更好地做到这一点吗?
我正在寻找的不是构建数据的更好方法,而是改进getPerson。 (在我的真实项目中,现在不可能更改数据结构)。
这是TypeScript Playground的链接。
非常感谢!
【问题讨论】:
标签: typescript typescript-generics