英文:
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
  }
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论