有多种方法.一般来说,函数的参数类型是静态的,不依赖于任何东西. 如果您希望函数的参数类型相互依赖,则必须使用通用参数、重载参数或go struct 化剩余参数,具体取决于您的用例.从调用者的Angular 来看,它们都表现得相当好,但test()
的实现者可能会发现某些方法比其他方法更好.
您可以将test
变成firstParam
的类型K
中的通用类型,并将secondParameter
写成模仿您的伪代码的condtional type:
function test<K extends EvtType>(
firstParam: K,
secondParameter: K extends "isText" ? string : number
) {
//...
}
test('isText', 2)// error
test('isText', "hey")// works
在某些用例中,编译器比条件类型更有机会"理解"的另一种通用方法是创建一个助手接口和look up该接口中的类型:
interface ParamMap {
isText: string,
isNumber: number
}
function test<K extends keyof ParamMap>(
firstParam: K, secondParameter: ParamMap[K]
) {
//...
}
test('isText', 2)// error
test('isText', "hey")// works
完成此类事情的传统方法是重载,您只需编写单独的调用签名,然后编写实现:
function test(firstParam: "isText", secondParameter: string): void;
function test(firstParam: "isNumber", secondParameter: number): void;
function test(firstParam: "isText" | "isNumber", secondParameter: string | number) {
}
test('isText', 2)// error
test('isText', "hey")// works
最后,您可以使用一个discriminated union(满分tuple types)的go struct 化rest参数,它的行为就像调用者端的过载,但可以在实现中进行缩窄,这与过载不同:
function test(
...[firstParam, secondParameter]:
["isText", string] |
["isNumber", number]
) {
//...
}
test('isText', 2)// error
test('isText', "hey")// works
Playground link to code