好的,所以我需要一些高级的打字稿类型技巧。我有一个带有 2 个参数的函数,但我希望第二个参数类型取决于第一个参数类型。例如,如果我的第一个参数是一个数字,那么我的第二个参数需要是一个字符串,但是如果我的第一个参数是 Record,那么我的第二个参数是一个数字。我知道我可以做一些函数原型重载,但我希望它是动态的,所以它看起来像这样:
type Test = [number, string] | [Record<string, any>, number];
foo<Test>(34, "bar") // ok
foo<Test>({a:34}, 56) // ok
foo<Test>(34, 56) // error
foo<Test>({a:34}, "bar") // error
我没有打字稿方面的高级知识,无法自己解决,所以如果可能的话,我会找你们所有人指导我。
答案 0 :(得分:1)
您可以使用 tuple types for rest parameters,包括 unions 的此类元组。因此,您可以像这样将 unsigned char
声明为 generic 函数:
foo()
当您将 declare function foo<T extends readonly any[]>(...args: T): void;
指定为 Test
参数时,这会导致您的示例表现得完全一样:
T
如果您不需要 foo<Test>(34, "bar") // ok
foo<Test>({ a: 34 }, 56) // ok
foo<Test>(34, 56) // error
foo<Test>({ a: 34 }, "bar") // error
是通用的,那么您可以硬编码 foo()
其余元组参数:
Test
无论哪种方式都行。 TypeScript 将 unions-of-rest-tuples 视为类似于 overloads,甚至 IntelliSense 中的 quickinfo 也会将它们显示为重载:
declare function bar(...args: Test): void;
bar(34, "bar") // ok
bar({ a: 34 }, 56) // ok
bar(34, 56) // error
bar({ a: 34 }, "bar") // error
答案 1 :(得分:0)
您可以将第一个参数定义为扩展 T
的泛型类型 number | Record<string, any>
,然后将第二个参数类型定义为有条件地依赖类型 T
:
function foo<T extends number | Record<string, any>>(
x: T, y: T extends number ? string : number) {
}