typescript - Jak deklarujete typ omezený hodnotami?
Ada
type Year_type is range 1800 .. 2100;
Raku
subset Natural of Int where * ≥ 0;
Kavorka
Int $even where { $_ % 2 == 0 }
TS
type Natural = BigInteger /* hypothetical → */ where (n) => { return n >= 0 };
Odpověď č. 1
Nemůžete, alespoň k verzi TS3.8.
Existuje otevřený návrh, microsoft/TypeScript#15480, který podporuje číselný typ s rozsahem; pokud chcete, aby se to stalo, možná budete chtít jít na tuto záležitost, dát jí 👍 a možná popsat svůj případ použití, pokud si myslíte, že je zvlášť přesvědčivý a není již zohledněn.
Pro typ „sudé číslo“ ve jednom z vašich příkladů byste potřebovali něco zcela jiného; pravděpodobně jako předpoklad by bylo potřeba, aby kompilátor mohl provádět aritmetiku na úrovni typu, což v současnosti nedělá. Stejně jako obvykle už pro to existuje otevřený problém, microsoft/TypeScript#26382, ale nevím, jestli se to někdy opravdu uskuteční. Závislé typy jsou skvělé, ale nevím, jestli se v dohledné době objeví v jazyce.
Do té doby je nejlepší, co můžete udělat, vytvořit typ podobný nominálnímu a uživatelem definovanou stráž typu, aby hodnoty mohly být správného typu. Ale všechno, co to dělá, je nutit vývojáře provádět spoustu testů za běhu pokaždé, když chtějí použít váš omezený typ, protože kompilátor to nemůže vynutit ani zkontrolovat:
type EvenNumber = number & { ___isEven: true };
function isEven(x: number): x is EvenNumber {
return x % 2 == 0;
}
function divideByTwoEvenly(x: EvenNumber): number {
return x / 2;
}
const a = divideByTwoEvenly(100); // error! 100 is not an EvenNumber
const hundred = 100;
if (isEven(hundred)) {
const a = divideByTwoEvenly(hundred);
} else {
throw new Error("I'm SAD");
}
Nic moc. No nic, doufám, že to pomůže; hodně štěstí!
Odkaz na kód na playgroundu
Odpověď č. 2
Pokud vím, zde není takový typ omezení nebo Range a jedním řešením může být vytvoření specifické třídy implementující tyto omezení.
Kromě toho vám unijní typy mohou pomoci s menšími rozsahy:
type EvenDigits = 0 | 2 | 4 | 6 | 8;
