typescript - Gör en strängliteraltyp till ett literalt värde


I TypeScript kan vi ha strängliteraltyper som tillåter oss att göra saker som:

type HelloString = "Hello";

Detta låter mig definiera något som en strängenum som följer:

namespace Literals {
    export type One = "one";
    export type Two = "two";
}

Och sedan kan jag definiera en union:

type Literal = Literals.One | Literals.Two;

Finns det ett sätt att extrahera det unika värdet av Literals.One som typen Literals.One?

Anledningen till detta är att när jag definierar en funktion på det här sättet:

function doSomething(literal : Literal) {

}

Jag skulle verkligen älska att göra följande:

doSomething(Literals.One);

Men jag kan inte. Jag måste skriva:

doSomething("one");

Svar #1

Du kan ha typer och värden med samma namn inom ett namnrymd, så du kan definiera konstanter för dessa värden:

namespace Literals {
    export type One = "one";
    export type Two = "two";
    export const One: One = "one";
    export const Two: Two = "two";
}

const s: Literals.One = Literals.One;
console.log(s);

Det finns ett förslag på GitHub för strängenumeraler, de föreslår att den nuvarande bästa lösningen är exemplet ovan.

Svar #2

Att omvandla en strängliteraltyp till ett literalt värde är möjligt med anpassade transformatorer (https://github.com/Microsoft/TypeScript/pull/13940), vilket finns i typescript@next.

Vänligen titta på mitt npm-paket, ts-transformer-enumerate.

Exempel på användning:

// The signature of `enumerate` here is `function enumerate<T extends string>(): { [K in T]: K };`
import { enumerate } from 'ts-transformer-enumerate';

type Colors = 'green' | 'yellow' | 'red';
const Colors = enumerate<Colors>();

console.log(Colors.green); // 'green'
console.log(Colors.yellow); // 'yellow'
console.log(Colors.red); // 'red'

Relaterade artiklar