首页 > 解决方案 > 如何限制使用类型中的键?

问题描述

我写了一个库

type State = {
  playing: boolean
  phases: {
    [key: string]: {
      progress: number
    }
  }
}

class BaseWidget {
  state: State

  constructor() {
    this.state = {
      playing: false,
      phases: {},
    }
  }
}

我这样用

class Widget extends BaseWidget {
    constructor() {
        super()
        this.state.phases = {
            start: {
                progress: 0,
            },
            finish: {
                progress: 0,
            },
        }
    }
}

继承的 BaseWidget 的不同类有不同的阶段
如何指定这个 Widget 类只有开始结束
是否可以从 Widget 类中以某种方式澄清 State 类型?
或者也许我需要使用泛型?
也许我需要使用的不是 [key: string],而是 [key in keyof T]?但是我如何通过 T 呢?什么是正确的语法?
谢谢!

标签: javascripttypescript

解决方案


你的问题有点宽泛,但看看你想要达到的目标,我会创造这样的东西:

type State = Record<string, any>;

class BaseWidget<S extends State> {
  state: S;

  constructor(initState: S) {
    this.state = initState;
  }
}

interface HasStartPhase {
  start: {
    progress: number;
  };
}

interface HasFinishPhase {
  finish: {
    progress: number;
    extraInfo: string;
  };
}

interface WidgetState extends State {
  playing: boolean;
  phases: HasStartPhase & HasFinishPhase;
}

class Widget extends BaseWidget<WidgetState> {
  constructor() {
    super({
      playing: false,
      phases: {
        start: {
          progress: 0
        },
        finish: {
          progress: 0,
          extraInfo: "abc"
        }
      }
    });
  }
}

它允许您的 BaseWidget 中的任何状态,并且特定的 Widget 可以指定自己的状态形状。为阶段创建接口允许您在需要时混合和匹配它们。

这是一个TS Playground供您尝试。


推荐阅读