简体   繁体   English

如何使用可选的唯一字符串定义数组 typescript 接口?

[英]How to define array typescript interface with optional unique strings?

I'd like to define an interface with optional string values.我想定义一个带有可选字符串值的接口。 Something like:就像是:

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

But with this interface I have problems:但是使用这个界面我有问题:

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

So are there ways to write the correct interface to avoid errors above?那么有没有办法写出正确的接口来避免上面的错误呢?

And perfectly without duplicated strings and not empty并且完全没有重复的字符串并且不为空

You can try to use an <> for the specific string.您可以尝试对特定字符串使用<>

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

Also, inspired by Nenroz, I think you can make use of type to group string as well.此外,受 Nenroz 的启发,我认为您也可以使用type对字符串进行分组。 Good to use when you have many different stuffs.当你有许多不同的东西时很好用。

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

interface IEntity {
  values: Array<Units> ;
}

It should fit for your case:它应该适合您的情况:

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

Maybe:也许:

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

interface IEntity {
  values?: Units[];
}

I don't think this is what the type system is for.我认为这不是类型系统的用途。 By enforcing this as a compile-time rule (which is all Typescript's typings ever are), you're ensuring that Typescript will only allow values that it can completely determine at compile time.通过将此作为编译时规则强制执行(这是所有 Typescript 的类型),您可以确保 Typescript 只允许它可以在编译时完全确定的值。 This would disallow in-place modification of an array, even one that would otherwise fit your rules.这将不允许对数组进行就地修改,即使是符合您规则的数组。 The usability cost of this interface would likely exceed the error-catching value it would give your API's consumers.此接口的可用性成本可能会超过它为您的 API 消费者提供的错误捕获价值。

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

Besides, Javascript has some effective ways to enforce non-duplicate behavior (sets or object keys) that would be very natural to what you want, and would also allow runtime behaviors that users would want (like being able to modify the list before passing it in).此外,Javascript 有一些有效的方法来强制执行非重复行为(集合或 object 键),这对于您想要的非常自然,并且还允许用户想要的运行时行为(例如能够在传递列表之前修改列表在)。

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

If you really want this, you'll need to spell it out:如果你真的想要这个,你需要把它拼出来:

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

typescript playground typescript游乐场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM