简体   繁体   English

Typescript 某类密钥

[英]Typescript keyof of a certain type

I am trying to do something like so, where I want to have a an idKey which is a keyof T but only the properties of type number.我正在尝试做类似的事情,我想要一个 idKey ,它是一个 keyof T 但只有数字类型的属性。

Is this possible?这可能吗?

export const updateList = <T>(
  idKey: keyof T extends number,
  list: T[],
  id: number
) => {
  const listItem = list.find(x => x[idKey] === id)
}

Having extends number is not right as gives an error, leaving it off also gives an error of:扩展编号是不正确的,因为它会产生错误,将其关闭也会产生以下错误:

This condition will always return 'false' since the types 'T[keyof T]' and 'number' have no overlap.此条件将始终返回 'false',因为类型 'T[keyof T]' 和 'number' 没有重叠。

If I understood your problem correctly, it is not the idKey itself that needs to be of type number , but rather the type T[keyof T] needs to extend type number.如果我正确理解了您的问题,则不是idKey本身需要是number类型,而是类型T[keyof T]需要扩展类型 number 。 So what you want to do is to restrict the T type to types that can be indexed with number .所以你想要做的是将T类型限制为可以用number索引的类型。 Something like this should work.像这样的东西应该工作。

export const updateList = <T extends { [key: number]: any }>(
  idKey: keyof T,
  list: T[],
  id: number
) => {
  const listItem = list.find(x => x[idKey] === id)
}

Playground 操场

The type system isn't strong enough to constrain idKey to keys for which T has a number value, but you can get around this by instead using a generic parameter K for the type of idKey and constraining the list elements to objects that have a number value for that key K .类型系统不够强大,无法将idKey限制为T具有数字值的键,但您可以通过使用通用参数K来代替idKey的类型并将list元素限制为具有数字的对象来解决此问题该键K的值。

const updateList = <K extends PropertyKey>(
  idKey: K,
  list: Record<K, number>[],
  id: number
) => {
  const listItem = list.find(x => x[idKey] === id)
  // ..
}

The builtin type PropertyKey is equal to string | number | symbol内置类型PropertyKey等于string | number | symbol string | number | symbol string | number | symbol (ie any valid property key type), and Record<K, number> (see docs ) stands for {[P in K]: number} . string | number | symbol (即任何有效的属性键类型),并且Record<K, number> (参见docs )代表{[P in K]: number} Basically, the type signature enforces that the list parameter is assignable to an array of singleton objects with an idKey number property, which also allows passing an array of objects with additional properties, as long as idKey has a number value.基本上,类型签名强制list参数可分配给具有idKey数字属性的 singleton 对象数组,这也允许传递具有其他属性的对象数组,只要idKey具有数字值。

Calls to updateList will now only type check correctly:updateList的调用现在只会正确输入检查:

const list = [{a: 8, b: 'x'}]

updateList('a', list, 0)

updateList('b', list, 0) // Error

Note that since the key parameter is leading the type inference, the error will be on the list parameter rather than on 'b' , but that shouldn't be a problem.请注意,由于 key 参数导致类型推断,因此错误将出现在list参数上而不是'b'上,但这应该不是问题。

TypeScript playground TypeScript操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM