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'
