Typescript根据另一个属性类型添加可选属性

bkhjykvo  于 2023-05-01  发布在  TypeScript
关注(0)|答案(3)|浏览(212)

我有一个与行动的属性接口,根据行动的类型,我想有可选的属性添加到接口。下面是当前界面

const FIGHT = `fight`;
const SWIM = `swim`;
const DANCE = `dance`;

type ActionType =
  | typeof FIGHT
  | typeof SWIM
  | typeof DANCE

interface Creator {
  actionType: ActionType;
  typeId: string;
}

如果actionType接收SWIM类型的值,那么我们需要向Creator接口添加一个附加属性,如

interface Creator {
  actionType: ActionType;
  typeId: string;
  trained?: string;
}

我的尝试,Creator

interface CreatorBase {
  actionType: ActionType;
  typeId: string;
}

interface CreatorSwim extends CreatorBase {
  actionType: typeof SWIM;
  trained?: string;
}

export type Creator = 
| CreatorBase
| CreatoeSwim

我得到错误TS2339:如果我尝试访问类型为Creator的对象的swim属性,则类型“Creator”上不存在属性“trained”。

4ktjp1zp

4ktjp1zp1#

这就是诀窍:

type ActionType =
  | 'fight'
  | 'swim'
  | 'dane'

interface CreatorBase<TActions> {
  typeId: string;
  actionType:  TActions
}

interface UntrainedCreator extends CreatorBase<Omit<ActionType, 'swim'>>
{
}

interface CreatorSwim  extends CreatorBase<'swim'> {
  trained?: string;
}

export type Creator = 
| UntrainedCreator
| CreatorSwim

const swim: Creator = {actionType: 'swim', typeId : 'i', trained: 'yes'};
const  dane : Creator = {actionType: 'dane', typeId : 'i', };
const  daneError : Creator = {actionType: 'dane', typeId : 'i', trained: ''}; // error

Playground

x8goxv8g

x8goxv8g2#

所以在这种情况下,我会想象条件类型是你的救星。你可以检查你的动作类型是否真的是“游泳”,如果是的话,你可以在你想要添加的按键上进行Map。
请看下面的代码片段:

type ActionType = "swim" | "run" | "walk"

type Creator <T extends ActionType> = {
    actionType: T
    type: string
} & {[k in T extends "swim" ? 'trained' : never]?: any}

const x: Creator<"swim"> = {
actionType: "run",
type: "swim",
trained: true
}
w6mmgewl

w6mmgewl3#

type ActionType =
  | 'fight'
  | 'swim'
  | 'dane'

interface Trained {
  playerNumber: number,
  type: string
}

interface CreatorBase {
  typeId: string;
  actionType:  ActionType
}

interface UntrainedCreator extends CreatorBase
{
  trained?: never;
}

interface CreatorSwim  extends CreatorBase {
  actionType: 'swim'
  trained?: Trained;
}

export type Creator = 
| UntrainedCreator
| CreatorSwim

相关问题