强制字符串类型成为TypeScript中字符串数组的一部分

时间:2019-07-01 22:58:49

标签: typescript

假设我具有以下界面:

interface Option {
  options: string[];
  symbolOption: string;
}

如何强制symbolOption数组中必须包含options

我需要的例子

这会没事的:

const option: Option = {
  options: ['a', 'b'],
  symbolOption: 'a' // ✅ OK
};

但这不会 可以:

const option: Option = {
  options: ['a', 'b'],
  symbolOption: 'c' // ? `c` is not included in the `options` list.
};

2 个答案:

答案 0 :(得分:1)

这有效(playground),尽管我不确定是否提供'a' | 'b'的通用参数是否适合您的要求。

interface Option<T> {
    options: T[];
    symbolOption: T;
}

// This will be OK:
const optionGood: Option<'a' | 'b'> = {
    options: ['a', 'b'],
    symbolOption: 'a' // ✅ OK
};

// But this will not be OK:
const optionBad: Option<'a' | 'b'> = {
    options: ['a', 'b'],
    symbolOption: 'c' // ? `c` is not included in the `options` list.
};

这里是jcalzplayground)的另一种替代礼貌。

interface OptionConstraint<
  T extends string,
  O extends OptionConstraint<T, O>
> {
  options: T[];
  symbolOption: O["options"][number];
}

const asOption = <T extends string, O extends OptionConstraint<T, O>>(o: O) =>
  o;

// This will be OK:
const optionGood = asOption({
  options: ["a", "b"],
  symbolOption: "a" // ✅ OK
});

// But this will not be OK:
const optionBad = asOption({
  options: ["a", "b"],
  symbolOption: "c" // ? `c` is not included in the `options` list.
});

答案 1 :(得分:0)

如果我了解您的要求,那将很简单:

interface Option {
  options: Array<'a'|'b'>;
  symbolOption: string;
}

修改 根据评论进行编辑。

您的要求是不可能的,TypeScript在很大程度上是一种编译类型检查,您不能使用动态类型值来表示接口类型。

阅读How to check the object type on runtime in TypeScript?可以了解运行时可以做什么和不能做什么