好的,我需要一些高级的打字技巧。我有一个接受2个参数的函数,但我希望第二个参数类型依赖于第一个参数类型。例如,如果我的第一个参数是一个数字,那么我的第二个参数需要是一个字符串,但是如果我的第一个参数是记录,那么我的第二个参数就是一个数字。我知道我可以做一些函数原型重载,但我希望它是动态的,所以它看起来像这样:
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我自己没有typescript的高级知识来解决这个问题,所以我来找你们所有人来指导我,如果这是可能的话。
发布于 2021-08-01 01:48:43
您可以使用tuple types for rest parameters,包括此类元组的unions。因此,您可以将foo()声明为generic函数,如下所示:
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 rest元组参数:
declare function bar(...args: Test): void;
bar(34, "bar") // ok
bar({ a: 34 }, 56) // ok
bar(34, 56) // error
bar({ a: 34 }, "bar") // error无论哪种方式都行得通。TypeScript将rest元组的联合视为类似于overloads,甚至IntelliSense中的quickinfo也会将它们显示为重载:
bar(/* hints */)
// 1/2 bar(args_0: number, args_1: string): void
// 2/2 bar(args_0: Record<string, any>, args_1: number): void发布于 2021-08-01 01:45:59
您可以将第一个参数定义为扩展number | Record<string, any>的泛型类型T,然后将第二个参数类型定义为有条件地依赖于类型T
function foo<T extends number | Record<string, any>>(
x: T, y: T extends number ? string : number) {
}https://stackoverflow.com/questions/68606844
复制相似问题