首页 > 解决方案 > 嵌套拾取定义

问题描述

如果我有一个带有嵌入式对象的接口,例如:

interface IStudent {
    name: string;
    address: {
        lineOne: string;
        lineTwo: string;
    }
}

const getAddressLineOne = (student: Pick<IStudent, 'address'>) => student.address.lineOne;

对于函数的定义,我真的只关心选择 的lineOne部分address,但据我了解,Pick只允许我深入一层,而不是进一步说明我的意思。

有没有办法用打字稿做到这一点?

标签: typescript

解决方案


您可以创建自己的NestedPick类型:

type NestedPick<T, K extends string[]> = T extends object ? {
  [P in Extract<keyof T, K[0]>]: NestedPick<T[P], Tail<K>>
} : T

// get tail of tuple
type Tail<T extends any[]> = ((...args: T) => any) extends (head: any, ...tail: infer I) => any
  ? I : never

尚未测试边缘情况,但这可能是一个很好的起点。然后getAddressLineOne看起来像:

const getAddressLineOne = (student: NestedPick<IStudent, ['address', 'lineOne']>) =>
  student.address.lineOne;

// Test
declare const student: IStudent
const res = getAddressLineOne(student) // string

或者,您可以缩小getAddressLineOne函数参数:

const getAddressLineOne2 = (address: Pick<IStudent["address"], "lineOne">) => address.lineOne;

代码示例


推荐阅读