根据另一个属性类型推断属性的签名如何?

huangapple go评论58阅读模式
英文:

How to infer signature of property based on another property type?

问题

type AnimalType = "dog" | "fish";

interface DogMoveProps {
  legs: number;
}

interface FishMoveProps {
  fins: number;
}

interface Animal {
  type: AnimalType;
  move: (props: AnimalType extends "dog" ? DogMoveProps : FishMoveProps) => void;
}

const dog: Animal = {
  type: "dog",
  move(props) { // DogMoveProps should be automatically inferred
    // props.legs
  }
}
英文:

Consider the following example:

type AnimalType = "dog" | "fish";

interface DogMoveProps {
  legs: number;
}

interface FishMoveProps {
  fins: number;
}

interface Animal {
  type: AnimalType;
  move: (props) => void; // How should this be typed?
}

How can I enforce the type of props based on the value of Animal.type field?

const dog: Animal = {
  type: "dog",
  move(props) { // <-- DogMoveProps should be automatically inferred
    // props.legs
  }
}

答案1

得分: 1

你可以定义 AnimalType 和其关联的 Props 类型之间的映射,然后使用自索引的 mapped type 来自动创建基于该映射的 discriminated union

type AnimalType = "dog" | "fish";

interface DogMoveProps {
  legs: number;
}

interface FishMoveProps {
  fins: number;
}

type MoveProps = {
  "dog": DogMoveProps;
  "fish": FishMoveProps;
};

type Animal = {
  [K in AnimalType]: {
    type: K,
    move: (props: MoveProps[K]) => void;
  }
}[AnimalType];

const dog: Animal = {
  type: "dog",
  move(props) {
    props.legs
  }
};
英文:

You could define a mapping between AnimalType and their associated Props types, and then use a self-indexing mapped type to automatically create a discriminated union based on that mapping:

type AnimalType = "dog" | "fish";

interface DogMoveProps {
  legs: number;
}

interface FishMoveProps {
  fins: number;
}

type MoveProps = {
  "dog": DogMoveProps;
  "fish": FishMoveProps;
};

type Animal = {
  [K in AnimalType]: {
    type: K,
    move: (props: MoveProps[K]) => void;
  }
}[AnimalType];

const dog: Animal = {
  type: "dog",
  move(props) {
    props.legs
  }
};

Playground link

huangapple
  • 本文由 发表于 2023年5月10日 13:10:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76215089.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定