Zoeken op website

Typescript string literal-unietype


Ik heb een klasse-eigenschap met een type dat de unie is van meerdere string-literals:

public reaction? : 'haha' | 'wow' | 'angry' | 'sad' | 'like';

Wat ik probeerde te doen, was deze strings ergens anders in een soort array te definiëren en vervolgens gewoon de array in de eigenschapsdefinitie te gebruiken. Dus zoiets als:

allowedStrings = ['haha','wow','angry','sad','like'];
public reaction? : allowedStrings;

Ik begrijp dat het bovenstaande niet mogelijk is, maar het is het algemene idee. Biedt TypeScript iets dat het werk doet?

Antwoord #1

Sinds TypeScript 3.4 kunt u een type genereren van een runtime-waarde met behulp van const-asserties.

const allowedStrings = ['haha', 'wow', 'angry', 'sad', 'like'] as const;
type AllowedString = typeof allowedStrings[number]; // [number] is important here

// We can freely map over values
const mapped = allowedStrings.map((s) => s.toUpperCase());

// And use generated type to create type-safe functions
const process = (s: AllowedString) => {
  // Type of s is
  //    s: "haha" | "wow" | "angry" | "sad" | "like"
  return s;
};

Antwoord #2

Het hangt precies af van hoe je het van plan bent te gebruiken, maar een string enum kan je geven wat je zoekt:

enum ReactionKind {
    haha = 'haha',
    wow = 'wow',
    angry = 'angry',
    sad = 'sad',
    like = 'like'
}

const reaction: ReactionKind = ReactionKind.angry;

// Get the string value  
const stringValue = ReactionKind[reaction];

// Get the Enum from a string
const enumValue = ReactionKind['wow'];

Je kunt nog steeds de gewone tekenreekswaarden gebruiken waar je ze nodig hebt, maar je kunt ze gebruiken als een type en als een runtime-waarde, wat lijkt te zijn waar je naar op zoek bent.

Je zult ook merken dat bij string-enums, als je een string sleutel gebruikt bij het koppelen aan een enum, dit gecontroleerd wordt... zolang je --noImplicitAny gebruikt.

// Error
const enumValue = ReactionKind['wat'];

Gerelateerde artikelen