【问题标题】:Typecheck indexed value of type类型检查类型的索引值
【发布时间】:2021-07-07 20:15:11
【问题描述】:

我有一些通用接口:

interface IProps<T> {
    item: T;
    key: keyof T;
}

如何确保item[key] 是字符串或数字类型,以便item[key] 可用于索引Record&lt;string | number, string&gt;

我正在使用 typescript v3.9

【问题讨论】:

标签: typescript typescript-generics


【解决方案1】:

可以使用这样的自定义类型来代替泛型类型:

interface PropType {
   [key: string]: string | number;
}

【讨论】:

  • 我不知道要索引哪个键。 item[x] 中的 x 是什么?
  • 在这个例子中 x 可以是任何东西,但如果你知道属性只需将它们声明为字段,就可以将它们用于索引并且还有无限的其他属性,我假设你不知道哪些属性存在,因为您在这里使用的是泛型类型。
【解决方案2】:

我认为你正在寻找这样的东西:

interface IProps<T extends Record<string, string | number>> {
  item: T;
  key: keyof T;
}

type Test1 = IProps<{ age: 1 }> // ok
type Test2 = IProps<{ age: '42' }> // ok
type Test3 = IProps<{ age: ['42'] }> // error

【讨论】:

  • 这极大地限制了可以传递的T类型,确实解决了限制item[key]类型的问题
  • 据我所知,值应该是字符串或数字。我说的对吗?
【解决方案3】:

您可能想要一个更严格的类型,而不是使用keyof T,它只允许具有string | number 值的键。这是一个解决方案:

type KeysAssignableTo<T, V> = {[K in keyof T]: T[K] extends V ? K : never}[keyof T]

interface IProps<T> {
    item: T;
    key: KeysAssignableTo<T, string | number>;
}

例子:

const item = {foo: 1, bar: true}

// OK
const testOK: IProps<typeof item> = {item, key: 'foo'}
// error: Type 'bar' is not assignable to type 'foo'
const testBad: IProps<typeof item> = {item, key: 'bar'}

Playground Link

【讨论】:

  • 这肯定回答了我最初的问题,但我做了一个小编辑,更好地代表了我的实际用例,我仍然在这里遇到问题 -> typescriptlang.org/play?#code/…
猜你喜欢
  • 2016-11-07
  • 2011-05-21
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2020-09-18
相关资源
最近更新 更多