【问题标题】:Typescript: function that returns a predefined union typeTypescript:返回预定义联合类型的函数
【发布时间】:2021-01-23 22:09:10
【问题描述】:

TypeScript 中有没有一种方法可以对可以返回已指定联合类型的函数进行建模,例如下面示例中的 myFunc

type UnionType = {
  field: "one",
  value: "two"
} | {
  field: "a" | "b",
  value: "a1" | "b1" | "c1"
}

myFunc("one", "two") // OK
myFunc("a", "a1") // OK
myFunc("a", "b1") // OK
myFunc("b", "a1") // OK

myFunc("one", "a1") // ERROR: only allowed second argument should be "two"
myFunc("one", "a") // ERROR: only allowed second argument should be "two"
myFunc("a", "two") // ERROR: only allowed second argument should be "a1" or "b1" or "c1"

第一种天真的方法可能是这样的:

const myFunc = <T extends UnionType>(field: T["field"], value: T["value"]): UnionType => ({
  field,
  value,
})

由于参数不相关,因此无法编译。不知何故,我需要 value 受到 field 类型的约束。

谢谢

【问题讨论】:

    标签: javascript typescript types


    【解决方案1】:
    type InferValue<T extends UnionType, K extends UnionType["field"]> = 
    // Use `extends` keyword to limit, refer to TypeScript `Exclude` implementation
    T extends (
      // get the matching struct, but it cannot be used directly
      {
        field: K;
        value: any;
      } extends T
        ? T
        : never
    )
      ? T["value"]
      : never;
    
    const myFunc = <K extends UnionType["field"]>(
      field: K,
      value: InferValue<UnionType, K>
    ): any => ({ // any
      field,
      value,
    });
    

    【讨论】:

    • 太好了,非常感谢,这几乎正是我所需要的!我试图弄清楚为什么myFunc 需要返回any,因为看起来没有必要。此外,对于我的用例,我需要myFunc 专门返回UnionType。现在我通过返回对象的类型断言来解决它,但我正在尝试看看是否有办法避免它。
    • 返回any 不重要,也可以使用as UnionType
    猜你喜欢
    • 2022-10-12
    • 2020-02-25
    • 2020-07-05
    • 2021-04-19
    • 2021-05-26
    • 2021-03-18
    • 2023-01-21
    • 2020-07-31
    • 1970-01-01
    相关资源
    最近更新 更多