【问题标题】:Pick type by array of string按字符串数组选择类型
【发布时间】:2021-07-21 14:49:46
【问题描述】:

我有类型

type User = {
    firstName: string,
    lastName: string,
    age: string
}

我需要一个函数

const result =  fun<User>(['firstName', 'lastName'])

我需要 result 类型是 User 并选择 firstNamelastName。可以用 typeScript 做吗?

【问题讨论】:

标签: javascript typescript typing


【解决方案1】:

是的,这是可能的。我自己并没有想出这个解决方案,所以所有的功劳都归于 github 上的“drop-george”人:

type User = {
    a: number;
    b: number;
    c: number;
}

type ElementType < T extends ReadonlyArray < unknown > > = T extends ReadonlyArray<
  infer ElementType
>
  ? ElementType
  : never

function get<T, K extends (keyof T)[]>(v: T, keys: K): Pick<T, ElementType<K>> {
    return v
}

const user: User = {a: 1, b: 2, c: 3}
const v = get(user, ['a', 'b'])
const {a, b, c} = v // ERROR
const {a: a2, b: b2} = v // OK
const {a: a3} = v // OK
get({a: 1, b: 2, c: 3} as User, ['a', 'b', 'otherKey']) // ERROR

Original source

UPD:您可以只使用ElementType&lt;K&gt; 而不是ElementType&lt;typeof keys&gt;

UPD2:AFAIK 如果你想制作类似fun&lt;User&gt;(['firstName', 'lastName']) 的东西,唯一的两种方法是:

  • 指定您需要两次的属性:
function get<T, K extends (keyof T)[]>(keys: K): Pick<T, ElementType<K>> {
    // return user
}

const user = get<User, ['firstName', 'lastName']>(['firstName', 'lastName'])
  • 或者创建一个返回另一个函数的函数,有点像这样:
function get<T>(): <K extends (keyof T)[]>(keys: K) => Pick<T, ElementType<K>> {
    return keys => {
        // return user from db
    }
}

const user = get<User>()(['firstName', 'lastName'])

【讨论】:

  • 我怎样才能使用get&lt;UserType&gt;(['a', 'b']) 之类的东西,例如get 它是对数据库或其他地方的调用?
  • @RuslanGlaznyov 我更新了答案(虽然还没有测试太多)
【解决方案2】:

我认为Typescript utility type 可以帮助您,特别是Pick 实用程序类型

type User = {
    firstName: string,
    lastName: string,
    age: string
}

type UserName = Pick<User, "firstName" | "lastName">;

const example: UserName = {
  firstName: "mo",
  lastName: "mo",
  age: "mo" // Typescript error
}

【讨论】:

  • 很酷,但我需要动态进行。选择;取决于 ['firstName', 'lastName'] 数组
猜你喜欢
  • 2022-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 1970-01-01
相关资源
最近更新 更多