首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >类型记录未正确识别的泛型类型

类型记录未正确识别的泛型类型
EN

Stack Overflow用户
提问于 2021-11-30 08:48:29
回答 1查看 594关注 0票数 3

我们有以下TypeScript代码:

代码语言:javascript
运行
复制
type Option = {
  name: string;
};

export const filterOptions = <T extends string>(
  options: Record<T, Option>,
): unknown[] =>
  Object.entries(options)
    .map(([key, entry]) => ({
      key,
      ...entry, // <--- Error: Spread types may only be created from object types.
    }))
    .filter(() => {
      // do filtering stuff...
    });

预期的entry类型是Option,但TS不承认这一点,并假设它是unknown。问题似乎是泛型类型T,因为将options类型更改为Record<string, Option>entry类型更改为Option (如预期的那样)。

这是一个TS游乐场连接

我们搞错什么了?为什么这种类型没有得到正确的识别?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-11-30 10:04:42

我刚刚检查了Object.entries()的输入:

代码语言:javascript
运行
复制
    /**
     * Returns an array of key/values of the enumerable properties of an object
     * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
     */
    entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];

备选案文1

似乎,您可以显式地将值参数类型传递给Object.entries()。这样,它就可以对typings进行正则化。

代码语言:javascript
运行
复制
const filterOptions = <T extends string>(
  options: Record<T, Option>,
) => {

  return Object.entries<Option>(options) // added option type here!
  .map(([key, entry]) => ({
      key,
      ...entry, // It knows for sure now..
  }))
  .filter(() => {
      // do filtering stuff...
  });
}

选项2

Record类型使用symbols / numbersstrings作为键。

代码语言:javascript
运行
复制
/**
 * Construct a type with a set of properties K of type T
 */
 type Record<K extends keyof any, T> = {
  [P in K]: T;
};

例如,这确实有效:

代码语言:javascript
运行
复制
const d = Symbol('somedescripton')

const a: Record<string, Option> = {
  'a': {name: 'strrst'},
  b: {name:'sdfsdf'},

  0: {name: 'srfsdfds'},
  d: {name: 'sdfsdfd'}
}

Object.entries()将将其转换为string键,但它仍然接受,Symbolsnumbers也是如此!^因此,对于只有string键的Record类型,您需要自己键入才能省略显式强制转换:

代码语言:javascript
运行
复制
type StringRecord<T extends string, K> = {[key in keyof T]: K }

const filterOptions = <T extends string>(
  options: StringRecord<T, Option>,
) => {

  return Object.entries(options)
  .map(([key, entry]) => ({
      key,
      ...entry, // works now.. 
  }))
  .filter(() => {
      // do filtering stuff...
  });
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70166541

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档