javascript - T 将 String 扩展为映射类型的索引

标签 javascript typescript generics typescript-generics mapped-types

在我的项目中,我使用映射类型(以 string 作为键):

export type ConfigurableFieldsType<T extends string[]> = {
  [field in keyof T]: string
}

在以下方法中,我使用类型(this.configurableFields 是一个 ConfigurableFieldsType 对象):

  private getConfigurableAttribute(attribute: C[number]): string {
    return this.configurableFields[attribute]
  }

但是,我收到错误:

Type 'C[number]' cannot be used to index type 'ConfigurableFieldsType<C>'.

您可以在 TS Playground 中找到完整的示例(带有可重现的错误)或以下内容:

export type ProductType<T extends string[]> = {
  // more variables
  configurableFields: ConfigurableFieldsType<T>
}

export type ConfigurableFieldsType<T extends string[]> = {
  [field in keyof T]: string
}

export class Product<C extends string[]> implements ProductType<C> {
  constructor(
    // more public parameters
    public configurableFields: ConfigurableFieldsType<C>,
  ) {}

  private getConfigurableAttribute(attribute: C[number]): string {
    return this.configurableFields[attribute]
  }
}

最佳答案

您打算ConfigurableFieldsType<["a", "b", c"]>评估类似 {a: string, b: string, c: string} ,但您当前的定义将导致 [string, string, string] 。那是因为{[K in keyof T]: string}结果是 mapped array type ; T是一个类似数组的类型,并且 keyof T因此是数组键,例如 "push""length" .

相反,您希望类型的键是 T元素 。也就是说,当你 index into 时你得到的类型T带有数字索引...所以而不是 keyof T ,你想要T[number] :

export type ConfigurableFieldsType<T extends string[]> = {
  [K in T[number]]: string
}

type Example = ConfigurableFieldsType<["a", "b", "c"]>
/* type Example = {
    a: string;
    b: string;
    c: string;
} */

现在一切都按照您的预期进行了:

private getConfigurableAttribute(attribute: C[number]): string {
  return this.configurableFields[attribute] // okay
}

Playground link to code

关于javascript - T 将 String 扩展为映射类型的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73042334/

相关文章:

javascript - 为什么这些 Date 对象不同?

typescript - ionic 滑动手势不适用于手机

TypeScript 0.9.5 - ...args : any[] dead in the water?(查看 Q.d.ts)

javascript - 如何通过 Javascript 获取 Bootstrap 版本?

javascript - 查看 YUI 的源代码并想知道一些事情

java - Java中的高级泛型

c# - Curiously Recurring Template Pattern 和泛型约束 (C#)

entity-framework - 错误 : The type 'TEntity' must be a reference type

javascript - 如何在浏览器中同步 ajax 调用期间显示等待消息

angular - 从服务返回的 Observable 的单元测试值(使用异步管道)