对于返回作为原始对象子集的对象的函数,类型定义会是什么样子 [英] What would the type definition look like for a function that returns an object that is a subset of an original object

查看:22
本文介绍了对于返回作为原始对象子集的对象的函数,类型定义会是什么样子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有一个(非常非常)大的对象,我想要一个函数,它接受任何对象 (T) 及其键列表(K 扩展 keyof T)并返回一个新对象只有那些传入的键/值.本质上是 {[key: K]: string}.

So, I've got a (very, very) large object, and I want to have a function that takes in any object (T) and a list of its keys (K extends keyof T) and returns a new object with only those keys/values that were passed in. Essentially {[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' 下失败.

I have been trying to write the type definition for this function, but it fails under 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(和打字稿)根据传入的内容知道该对象的外观.我已经有了一个资源类型.可能有一种与我在这里开始的方法完全不同的方法,我只是不知道如何开始输入这个.

My goal here is to get that subset object, and have my IDE (and typescript) know what the object looks like based on what was passed in. I already have a type for resources. There may be a wholly different approach than how I've started here, I'm just not sure how else to even start typing this.

推荐答案

你已经很接近了;您正在寻找 映射类型,它允许您迭代键(而不是使用索引器).也就是说,不要使用这个:

You're pretty close; you're looking for mapped types which allow you to iterate over keys (as opposed to using an indexer). That is, don't use this:

{[key: K]: IResources[K]}

改用这个:

{[P in K]: IResources[P]}

事实上,这是一个足够有用的结构,它存在于 标准库 as Pick:

In fact, this is a useful enough construct that it exists in the standard library as Pick<T,K>:

Pick<IResources, K>

所以你的函数变成了这样:

So your function becomes something like:

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 上的传播类型.如果您确定实现中的一切都很好,您可以使用 any 断言来帮助:

This will fail to type check in the implementation because I don't think TypeScript understands the spread type on Pick<IResources, K>. If you're sure everything in the implementation is fine, you can use an any assertions to help:

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 是什么,我无法轻松做到).希望有所帮助;祝你好运!

You can verify that this behaves as desired (I can't easily do it without knowing what IResources is). Hope that helps; good luck!

这篇关于对于返回作为原始对象子集的对象的函数,类型定义会是什么样子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆