对于 returns 作为原始对象子集的对象的函数,类型定义是什么样的
What would the type definition look like for a function that returns an object that is a subset of an original object
所以,我有一个(非常非常)大的对象,我想要一个函数来接收任何对象 (T) 及其键列表(K extends keyof T)和 returns 一个新对象,只有那些 keys/values 被传入。本质上是 {[key: K]: string}.
这里是有问题的函数:
export function mapResources(resources, keys: string[]) {
return keys.reduce((response, key) => ({
...response,
[key]: resources[key]
}), {});
}
我一直在尝试为这个函数编写类型定义,但在 TS1023: An index signature parameter type must be 'string' or 'number'.
下失败了
export function mapResources<K extends keyof IResources>(resources: IResources, keys: K[]): {[key: K]: IResources[K]} {
return keys.reduce((response, key) => ({
...response,
[key as string]: resources[key]
}), {});
}
我的目标是获取该子集对象,并让我的 IDE(和打字稿)根据传入的内容知道对象的外观。我已经有了资源类型。可能有一种与我在这里开始的方法完全不同的方法,我只是不确定如何开始输入这个。
你很接近;您正在寻找 mapped types ,它允许您迭代键(而不是使用索引器)。也就是说,不要使用这个:
{[key: K]: IResources[K]}
改用这个:
{[P in K]: IResources[P]}
事实上,这是一个足够有用的结构,它存在于 standard library 中,如 Pick<T,K>
:
Pick<IResources, K>
所以你的函数变成这样:
export function mapResources<K extends keyof IResources>(resources: IResources, keys: K[]): Pick<IResources, K> {
return keys.reduce((response, key) => ({
...response,
[key as string]: resources[key]
}), {});
}
这将无法在实现中进行类型检查,因为我认为 TypeScript 不理解 Pick<IResources, K>
上的传播类型。如果您确定实施中的一切都很好,您可以使用 any
断言来帮助:
export function mapResources<K extends keyof IResources>(resources: IResources, keys: K[]): Pick<IResources, K> {
return keys.reduce((response, key) => ({
...(response as any),
[key]: resources[key]
}), {});
}
您可以验证这是否按预期运行(如果不知道 IResources
是什么,我无法轻易做到)。希望有所帮助;祝你好运!
所以,我有一个(非常非常)大的对象,我想要一个函数来接收任何对象 (T) 及其键列表(K extends keyof T)和 returns 一个新对象,只有那些 keys/values 被传入。本质上是 {[key: K]: string}.
这里是有问题的函数:
export function mapResources(resources, keys: string[]) {
return keys.reduce((response, key) => ({
...response,
[key]: resources[key]
}), {});
}
我一直在尝试为这个函数编写类型定义,但在 TS1023: An index signature parameter type must be 'string' or 'number'.
export function mapResources<K extends keyof IResources>(resources: IResources, keys: K[]): {[key: K]: IResources[K]} {
return keys.reduce((response, key) => ({
...response,
[key as string]: resources[key]
}), {});
}
我的目标是获取该子集对象,并让我的 IDE(和打字稿)根据传入的内容知道对象的外观。我已经有了资源类型。可能有一种与我在这里开始的方法完全不同的方法,我只是不确定如何开始输入这个。
你很接近;您正在寻找 mapped types ,它允许您迭代键(而不是使用索引器)。也就是说,不要使用这个:
{[key: K]: IResources[K]}
改用这个:
{[P in K]: IResources[P]}
事实上,这是一个足够有用的结构,它存在于 standard library 中,如 Pick<T,K>
:
Pick<IResources, K>
所以你的函数变成这样:
export function mapResources<K extends keyof IResources>(resources: IResources, keys: K[]): Pick<IResources, K> {
return keys.reduce((response, key) => ({
...response,
[key as string]: resources[key]
}), {});
}
这将无法在实现中进行类型检查,因为我认为 TypeScript 不理解 Pick<IResources, K>
上的传播类型。如果您确定实施中的一切都很好,您可以使用 any
断言来帮助:
export function mapResources<K extends keyof IResources>(resources: IResources, keys: K[]): Pick<IResources, K> {
return keys.reduce((response, key) => ({
...(response as any),
[key]: resources[key]
}), {});
}
您可以验证这是否按预期运行(如果不知道 IResources
是什么,我无法轻易做到)。希望有所帮助;祝你好运!