typescript 如何用可选的唯一字符串定义数组类型脚本接口?

2nc8po8w  于 2023-06-30  发布在  TypeScript
关注(0)|答案(5)|浏览(113)

我想用可选的字符串值定义一个接口。类似于:

interface IEntity {
    values: ['RemainingUnits', 'ActualUnits', 'PlannedUnits']
}

但是这个界面有问题:

const entity0: IEntity = { values: ['PlannedUnits'] }; // => Error
const entity1: IEntity = { values: ['RemainingUnits', 'ActualUnits'] }; // => Error
const entity2: IEntity = { values: ['PlannedUnits', 'RemainingUnits', 'ActualUnits'] }; // => Error

那么,有没有办法编写正确的接口来避免上面的错误呢?
完全没有重复的字符串并且不为空

a11xaf1n

a11xaf1n1#

可能:

type Units = 'RemainingUnits' | 'ActualUnits' | 'PlannedUnits';

interface IEntity {
  values?: Units[];
}
3ks5zfa0

3ks5zfa02#

您可以尝试对特定字符串使用<>

interface IEntity {
    values: Array<'RemainingUnits' | 'ActualUnits' | 'PlannedUnits'>
}

另外,受Nenroz的启发,我认为你也可以使用type来分组字符串。当你有很多不同的东西时,很好用。

type Units = 'RemainingUnits' | 'ActualUnits' | 'PlannedUnits';

interface IEntity {
  values: Array<Units> ;
}
g2ieeal7

g2ieeal73#

我不认为这是类型系统的作用。通过将其作为编译时规则(这是Typescript的所有类型)来强制执行,可以确保Typescript只允许它在编译时可以完全确定的值。这将不允许对数组进行就地修改,即使是符合您的规则的数组。这个接口的可用性成本可能会超过它为API的使用者提供的错误捕获值。

let array: Units = ['RemainingUnits'];
if (condition) {
  array.push('ActualUnits');  // not allowed; Typescript can't reason about it
}
return array;

此外,JavaScript有一些有效的方法来强制执行非重复的行为(集合或对象键),这对你想要的东西来说是非常自然的,并且还允许用户想要的运行时行为(例如能够在传递列表之前修改它)。

type Units = {
  RemainingUnits: boolean,
  ActualUnits: boolean,
  PlannedUnits: boolean
}

如果你真的想要这个,你需要把它拼出来:

type A = 'RemainingUnits';
type B = 'ActualUnits';
type C = 'PlannedUnits';

type Units = [A] | [B] | [C]
  | [A, B] | [A, C] | [B, A] | [B, C] | [C, A] | [C, B]
  | [A, B, C] | [A, C, B] | [B, A, C] | [B, C, A] | [C, A, B] | [C, B, A];

interface IEntity {
  values: Units;
}

const example1: IEntity = { values: ['RemainingUnits', 'PlannedUnits'] }
const example2: IEntity = { values: ['RemainingUnits', 'RemainingUnits'] }  //error
const example3: IEntity = { values: [] }  //error

打字游戏场

juud5qan

juud5qan4#

它应该适合你的情况:

type Units = 'RemainingUnits' | 'ActualUnits' | 'PlannedUnits';

interface IEntity {
    values: [Units, Units?, Units?]
}

const entity0: IEntity = { values: ['PlannedUnits'] }; // success
const entity1: IEntity = { values: ['RemainingUnits', 'ActualUnits'] }; // success
const entity2: IEntity = { values: ['PlannedUnits', 'RemainingUnits', 'ActualUnits'] }; // success
mkshixfv

mkshixfv5#

这是一个固定长度的数组类型(又名元组),在固定位置有可选的文字字符串类型。
不允许重复。我看到的唯一缺点是,如果您只想提供后面的值,则必须从undefined开始。这是没办法的事

interface IEntity {
  values: ['RemainingUnits'?, 'ActualUnits'?, 'PlannedUnits'?];
}

示例:

const myIEntity: IEntity = { values: [undefined, 'ActualUnits'] };

相关问题