Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

javascript - Typescript: function that returns a predefined union type

Is there a way in TypeScript to model a function that can return an already specified union type, like myFunc in the example below?

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"

A first naive approach might be something like this:

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

Which doesn't compile because the arguments are not dependent. Somehow I need value to be constrained by the type of field.

Thanks

question from:https://stackoverflow.com/questions/65854237/typescript-function-that-returns-a-predefined-union-type

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
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,
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...