【发布时间】:2021-05-05 01:13:43
【问题描述】:
上下文
我无法确定是否可以在类型中为泛型参数使用隐含值,这与在函数中可能使用的方式相同。
假设我有以下接口定义我的一些数据库表的结构:
interface Tables {
'table-users': { userId: string, username: string },
'table-posts': { postId: string, userId: string, title: string },
}
我可以编写一个过于简化的函数,允许我使用以下方法写入这些表:
const write = <T extends keyof Tables>(table: T, item: Tables[T]): boolean => {
// ... do something
return true;
}
这让我可以这样做
write('table-users', { userId: '123', username: 'John Doe' }); // ✅
write('table-posts', { postId: 'abc', userId: '123', title: 'First Post' }); // ✅
但不是
write('table-users', { postId: 'abc' }); // ❌
write('table-posts', { userId: 'abc' }); // ❌
到目前为止,一切都很好。
问题
但是,现在我希望能够构造一个类型(类似于函数),该类型需要一个需要为表名的属性,并且该类型中的另一个属性需要具有正确的项目格式。
我认为这些方面的东西应该可以工作:
type Item<T extends keyof Tables> = {
table: T,
item: Tables[T],
}
并自动允许:
const userItem: Item = {
table: 'table-users',
item: {
userId: '1',
username: 'John Doe',
}
};
const postItem: Item = {
table: 'table-posts',
item: {
postId: '123',
userId: '1',
username: 'John Doe',
}
};
或者只是使用Item作为函数参数类型提示,但它没有,因为它总是需要显式定义表名:
const userItem: Item<'table-users'> = {
table: 'table-users',
item: {
userId: '1',
username: 'John Doe',
}
};
const postItem: Item<'table-posts'> = {
table: 'table-posts',
item: {
postId: '123',
userId: '1',
title: 'First Post',
}
};
任何线索是否可以在 TypeScript 中寻找我正在寻找的东西?我认为它应该是,因为它可能是并且我可能只是在做一些愚蠢的事情,但我似乎无法修复它。
编辑
相比之下,这个是有效的:
type Item = {
[T in keyof Tables]?: {
item: Tables[T]
}
}
但我希望这样做,但使用 T 作为值,而不是键。
【问题讨论】:
标签: typescript generics types