打字稿:返回预定义联合类型的函数

时间:2021-01-22 23:45:26

标签: javascript typescript types

在 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,
})

无法编译,因为参数不相关。不知何故,我需要 valuefield 类型的约束。

谢谢

1 个答案:

答案 0 :(得分: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,
});