【问题标题】:second parameter type depends on first param in typescript第二个参数类型取决于打字稿中的第一个参数
【发布时间】:2021-08-01 01:26:23
【问题描述】:

好的,所以我需要一些高级打字稿类型技巧。我有一个带有 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

我没有打字稿方面的高级知识来自己弄清楚,所以我来找你们所有人指导我,如果这可能的话。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您可以使用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 其余元组参数:

    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 将 unions-of-rest-tuples 视为类似于 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
    

    Playground link to code

    【讨论】:

    • 有没有办法动态访问第二种类型?因为这样我就不能做类似declare foo&lt;T extends any[]&gt;(a: T[0], b: someClass&lt;T[1]&gt;): void;
    • 我不确定我是否理解您要查找的内容...是否类似于 this?如果没有,您能否详细说明,最好使用minimal reproducible example 显示接受/拒绝什么的用例?
    【解决方案2】:

    您可以将第一个参数定义为泛型类型T,它扩展了number | Record&lt;string, any&gt;,然后第二个参数类型有条件地依赖于类型T

    function foo<T extends number | Record<string, any>>(
      x: T, y: T extends number ? string : number) {
    }
    

    Playground

    【讨论】:

    • 是的,这可行,但我需要它是动态的,这需要硬编码,这不是我想要的。
    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2023-02-13
    • 2018-03-22
    • 2021-11-20
    • 1970-01-01
    相关资源
    最近更新 更多