Comment exiger une chaîne spécifique dans l'interface TypeScript


144

Je crée un fichier de définition TypeScript pour une bibliothèque js tierce. L' une des méthodes permet d'un objet d'options, et l' une des propriétés de l'objet d'options accepte une chaîne dans la liste: "collapse", "expand", "end-expand"et "none".

J'ai une interface pour l'objet d'options:

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: // "collapse" | "expand" | "end-expand" | "none"
}

L'interface peut-elle appliquer cela, donc si vous incluez un IOptionsobjet avec la brace_stylepropriété, elle n'autorisera qu'une chaîne qui est dans la liste acceptable?


4
Veuillez revoir les réponses à cette question
— Andreas

Un peu dans le sens du commentaire de @Andreas, pourquoi préférez-vous la réponse de RyanQ à celle de Denis Khay ? Denis 'semble plus largement applicable à l'OMI.
— ruffin

Réponses:


226

Cela a été publié dans la version 1.8 en tant que "types littéraux de chaîne"

Nouveautés de Typescript - Types de littéraux chaîne

Exemple de la page:

interface AnimationOptions {
  deltaX: number;
  deltaY: number;
  easing: "ease-in" | "ease-out" | "ease-in-out";
}

6
Il faut copier et coller une ligne avec des chaînes partout où dans l'application vous auriez besoin de passer une chaîne de ce type comme argument. Si vous utilisez toujours des animationsOptions entières, cette solution semble correcte, mais pour les cas d'utilisation où vous ne pouvez passer que le type «easing», c'est faux. Voir la réponse de Denis Khay, c'est bien mieux.
— Patryk Wlaź

121

Essaye ça

export type ReadingTypes = 'some'|'variants'|'of'|'strings';

export interface IReadings {
   param:ReadingTypes
}

12
Cela doit être marqué comme correct, car il permet de réutiliser le type créé n'importe où dans une application.
— Patryk Wlaź

C'est exactement ce que je recherchais pour transmettre un tableau de chaînes en tant que valeurs à un type énuméré. En sautant complètement enum et en utilisant type, j'ai pu passer l'exemple suivant: const myVar: ReadingTypes = ["some"|"variants"];tout en conservant une syntaxe de typage dynamique enum. Tout à fait convenu que cela aurait dû être la réponse marquée comme correcte.
— mdawsondev

y a-t-il un moyen de l'utiliser mais doucement tapé comme celui-ci, type VisibilityTypes = VISIBILITY.PUBLISH | VISBIBILITY.DRAFTj'obtiens une erreur d'espace de noms non trouvée, mais lorsque je les code en dur, cela semble fonctionner
— Max Carroll

J'ai trouvé un moyen et ajouté une nouvelle réponse
— Max Carroll

10

Peut-être pas exactement ce que vous vouliez, mais cela Enumsemble être une solution parfaite pour vous.

enum BraceStyle {Collapse, Expand, EndExpand, None}

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style?: BraceStyle
}

Les énumérations sont cependant basées sur des nombres. Cela signifie que pendant l'exécution, une valeur réelle pour par exemple BraceStyle.Collapsesera 0 dans ce cas. Mais vous pouvez les utiliser avec d'autres scripts, même non dactylographiés, car ils se compilent en objets. Voici à quoi BraceStyleressemblera la compilation et l'exécution:

{
    0: "Collapse",
    1: "Expand",
    2: "EndExpand",
    3: "None",
    Collapse: 0,
    Expand: 1,
    EndExpand: 2,
    None: 3
}

Si vous voulez des chaînes à la place, vous pouvez utiliser une classe avec des membres statiques, comme décrit ici


enums peuvent avoir des valeurs de chaîne (maintenant du moins, je ne sais pas si elles le pourraient en 2014). enum BraceStyle { Collapse = "Collapse", Expand = "Expand" }.
— ZachB

S'ils le pouvaient en 2014, je le mentionnerais dans ma réponse.
— Kuba Jagoda

8

TS propose un typage de valeurs de chaîne spécifiques, appelées types de littéraux String .

Voici un exemple de leur utilisation:

type style =  "collapse" | "expand" | "end-expand" | "none";

interface IOptions {
  indent_size?: number;
  indent_char?: string;
  brace_style1?:  "collapse" | "expand" | "end-expand" | "none";
  brace_style2?:  style;
}

// Ok
let obj1: IOptions = {brace_style1: 'collapse'};

// Compile time error:
// Type '"collapsessss"' is not assignable to type '"collapse" | "expand" | "end-expand" | "none" | undefined'.
let obj2: IOptions = {brace_style1: 'collapsessss'};

1
function keysOf<T>(obj: T, key: keyof T) { return obj[key]; }
interface SomeInterface {
   a: string;
}
const instance: SomeInterface = { a: 'some value'};
let value = keysOf<SomeInterface>(instance, 'b'); // invalid
value =  keysOf<SomeInterface>(instance, 'a'); // valid

1

Dans TypeScript 2.4, vous pouvez utiliser des énumérations de chaînes

Je suis favorable à cette approche car elle évite d'avoir à avoir la même chaîne codée en dur à plusieurs endroits.

Il est possible de faire une énumération où les valeurs sont des chaînes

export enum VISIBILITY {
  PUBLISH = "publish",
  DRAFT = "draft"
}

Cette énumération peut ensuite être utilisée comme type sur une interface ou une classe

export interface UserOptions  {
  visibility:  VISIBILITY 
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.