请问ts中如果做接口/类型的筛选呢?

我不确定如何正确高效的使用type 与 interface ?
特效类型的枚举如果更多的话,这个类型将会更难描述。
如果在我需要混合写修改属性的函数时,_type再拆分成泛型,会在取值时报错。
貌似redux的状态管理也有这个情况,但我没搞明白他是怎么处理的。

/** 特效类型枚举 */
const enum effectType {
    linear,
    track,
    attach
}
/** 矢量 */
type Vector = [number,number,number]
/** 特效参数 */
interface effectInfo {
    model: string
    _type: effectType
  // 上面两个是必要的,下面三个是随着 _type 而变化的
    source: _type extends 0 ? Vector : undefined
    target:_type extends 0 ? Vector : _type extends 1 ? string : undefined
    point: _type extends 2 ? string : undefined
}

上面这个是需要重写的接口,下面这个是对类型的需求使用

export default class {
  /** 创建 */
  Create(info:effectInfo){
      this._list[this._list.length] = info
  }

  /** 修改属性 */
  SetState<K extends keyof effectInfo>(id: ParticleID, stateID: K, value: effectInfo[K]){
      this._list[id][stateID] = value
  }

  /** 触发一个特效 */
  fireLinear(info:effectInfo){
      if( info._type !== 0)
          console.error(info._type)
      if( type(info.target) !== Vector)
          console.error(info.target)
      if( info.point !== null)
          console.error(info.point)
      if( info.source && info.target)
          console.log('success')
  }
}
阅读 1.4k
1 个回答
enum EffectType {
  Linear,
  Track,
  Attach,
}

type Vector = [number, number, number];

interface LinearEffectInfo {
  _type: EffectType.Linear;
  model: string;
  source: Vector;
  target: Vector;
}

interface TrackEffectInfo {
  _type: EffectType.Track;
  model: string;
  target: string;
}

interface AttachEffectInfo {
  _type: EffectType.Attach;
  model: string;
  point: string;
}

type EffectInfo =
  | LinearEffectInfo
  | TrackEffectInfo
  | AttachEffectInfo;



export default class {
  private _list: EffectInfo[] = [];

  public create (info: EffectInfo) {
    this._list[this._list.length] = info;
  }

  public setState<K extends Exclude<keyof EffectInfo, "_type">> (id: number, stateID: K, value: EffectInfo[K]) {
    this._list[id][stateID] = value;
  }

  public fireLinear (info: EffectInfo) {
    if (info._type === EffectType.Linear) {
      console.log("success");
    }
    else {
      console.error(info._type);
    }
  }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进