gpt4 book ai didi

具有隐式属性类型的 Typescript 泛型

转载 作者:行者123 更新时间:2023-12-05 06:05:33 26 4
gpt4 key购买 nike

上下文

我无法确定是否可以对类型中的泛型参数使用隐含值,就像在函数中一样。

假设我有以下接口(interface)定义我的一些数据库表的结构:

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 作为值,而不是键。

最佳答案

您可以使用 conditional types像这样:

type ItemGeneric<T> = T extends keyof Tables ? {
table: T;
item: Tables[T];
} : never;

type Item = ItemGeneric<keyof Tables>;

这将根据您为 table 设置的字符串值隐式设置 item 的类型。 Here's a small demo这在行动中。

全部归功于nmain on github感谢您告诉我这件事。

关于具有隐式属性类型的 Typescript 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65982905/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com