【问题标题】:Typescript: Is it possible to force 'keyof T' to be a string?打字稿:是否可以强制“keyof T”为字符串?
【发布时间】:2021-09-22 09:10:46
【问题描述】:

我有一个函数类型如下:

const getByPrimaryKey = <E>(list: E[], primaryKey: keyof E): E => {...} 

我可以为与 primaryKey 关联的值添加类型验证吗?例如:

interface User {
  id: string
  name?: string
  age: number
}

const users: User[] = [{id: '1', age: 1}]

getByPrimaryKey<User>(users, 'id') // OK since id is a string
getByPrimaryKey<User>(users, 'name') // NOT OK because name maybe undefined
getByPrimaryKey<User>(users, 'age') // NOT OK because age is a number


【问题讨论】:

  • keyof T 在这种情况下是'id' | 'name' | 'age',所有这些都是字符串;我认为您的意思是您想要一个关联值为string 类型的键。所以你想要这个问答中的KeysMatching 类型:How to write PickByValue type?
  • 我更新了我的问题,使其更加清晰。我说的是值的类型。我刚刚回答了我自己的问题????
  • 我看不出您的问题与您自己的答案之间有任何关系。通过添加第二个类型参数,您打破了提供一个类型参数的用例示例,并且您的类型参数 PK 仅受 keyof E 限制,因此没有什么可以阻止它成为 'name''age'
  • 你是对的。我最初的问题从我的脑海中消失了,我发布了一个适用于我现实生活案例的解决方案。谢谢你提醒我。
  • 为什么getByPrimaryKey&lt;User&gt;(users, 'age') // NOT OK because age is a number不行?

标签: typescript typescript-generics


【解决方案1】:

你需要结合几个conditional types

获取所有非可选的键:

type RequiredKeys<T> = { [K in keyof T]-?: ({} extends { [P in K]: T[K] } ? never : K) }[keyof T];

获取所有具有特定类型值的键:

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

那么你可以使用两者的交集:

type NonOptionalTypeMatchingKeys<T, V> = TypeMatchingKeys<T, V> & keyof Pick<T, RequiredKeys<T>>;
const getByPrimaryKey = <E>(list: E[], primaryKey: NonOptionalTypeMatchingKeys<E, string>): E => {
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-16
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2022-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多