第二个函数参数的条件类型

时间:2019-07-01 09:14:30

标签: typescript literals typescript-generics

我具有以下功能:

function doSomething(param1: string, param2: string) {
  return param1 + param2;
}

我也有基于json的类型,其结构类似于此:

a1: {
  b1: 'something1',
  b2: 'something2',
  b3: 'something3'
},
a2: {
  c1: 'something4',
  c2: 'something5'
}

...etc

我希望提到的函数的第n个参数为第n个深层元素的文字,因此,如果第一个参数为'a1',第二个应该为'b1' | 'b2' | 'b3',如果第一个参数是'a2',则第二个应该是'c1' | 'c2'

对于第一个参数,我将类型简化为keyof typeof data,这很有效:

// data is imported json
type FirstArg = keyof typeof data;

我第二次尝试这样的通用类型,但没有成功:

type SecondArg<T extends FirstArg> = keyof typeof data[T];

有机会这样做吗?

1 个答案:

答案 0 :(得分:2)

您不能为任何数量的参数执行此操作,您可以为特定深度定义重载:

const data = {
    a1: {
        b1: 'something1',
        b2: 'something2',
        b3: 'something3'
    },
    a2: {
        c1: 'something4',
        c2: 'something5'
    }
}
type DataType = typeof data;
function doSomething<K extends keyof DataType, K2 extends keyof DataType[K]>(p1: K, p2: K2, p3: keyof DataType[K][K2]): string
function doSomething<K extends keyof DataType>(p1: K, p2: keyof DataType[K]): string
function doSomething(p1: keyof DataType): string
function doSomething(...keys: PropertyKey[]) {
    return keys.join('.');
}

doSomething("a1", "b1")
doSomething("a1", "c2") // err