首页 > 解决方案 > 我可以在 TypesScript 中使用泛型类型作为对象索引类型吗?

问题描述

我有一个类似于以下的用例:



type StringKeysOf<T> = [{
  [K in keyof T]-?: T[K] extends string ? K : never
}[keyof T]];

const createDictionary = <T>(key: StringKeysOf<T>) => {

  let dictionary: { [key: string]: T } = {};

  const addToDictionary = (value: T) => {
    dictionary = { ...dictionary, [value[key]]: value }
  }

  return { dictionary, addToDictionary }
}


当尝试使用 key 属性作为索引类型时,TypeScript 抱怨以下消息:Type 'StringKeysOf<T>' cannot be used as an index type.

我认为这是不可能的,因为T最终可能会持有一个没有任何类型属性的类型string(我正在过滤StringKeysOf条件类型)。

有谁知道是否有办法使这种实现成为可能?

标签: typescriptgenerics

解决方案


你可以做几件事来解决这个问题。首先,注意这StringKeysOf<T>是一个Array类型。给定 namekey而不是keys,我假设您的意思是参数是单个值。您需要删除[]

type StringKeysOf<T> = {
  [K in keyof T]-?: T[K] extends string ? K : never
}[keyof T];

然后,您需要确保您T的形状符合您的预期:

T extends { [K in keyof T]: any }

把它们放在一起:TS Playground

type StringKeysOf<T> = {
  [K in keyof T]-?: T[K] extends string ? K : never
}[keyof T];

const createDictionary = <T extends { [K in keyof T]: any }>(key: StringKeysOf<T>) => {

  let dictionary: { [key: string]: T } = {};

  const addToDictionary = (value: T) => {
    dictionary = { ...dictionary, [value[key]]: value }
  }

  return { dictionary, addToDictionary }
}

推荐阅读