To dla mnie najlepszy wynik w Google, więc myślę, że powinienem przedstawić rozwiązania, które znalazłem.
Za pomocą bigint
Teraz, gdy jest rok 2020 i bigintzostał zaakceptowany, zasługuje na wzmiankę. Możesz po prostu wykonać poniższe czynności. Pamiętaj, że bigintma to większy wpływ na wydajność w porównaniu z plikiem number.
const myNumber: bigint = 10n
Używanie typu nominalnego / oznaczonego / nieprzezroczystego
Alternatywą jest użycie typu nominalnego, ale jest on prawdopodobnie mniej ergonomiczny i nie jestem pewien, czy jest szybszy niż bigint, ale wzór uogólnia się na każdy typ, nie tylko number. TypeScript nie obsługuje tego typu „pierwszej klasy”, więc musisz zrobić bezczelny hack. Jest do tego biblioteka o nazwie, newtype-tsktóra zawiera typowe typy, Integerwięc możesz po prostu chcieć tego użyć, ale wyjaśnię poniżej działanie.
Na początek definiujemy integertyp.
const TAG = Symbol()
type integer = number & { readonly [TAG]: unique symbol }
Te TAG, zapewnia mamy unikalną wartość tak, że nie przypadkowo tworzenia obiektu z tego samego klucza, i robimy pole unikalny symbol też z tego samego powodu. Twoja liczba całkowita nie będzie miała tego pola obiektu, ale to dobrze.
Dzięki temu możesz nadal dodawać integerdo numberusing +. Niedobrze. Możesz więc wymusić bezpieczeństwo typów argumentów tutaj, masując system typów za pomocą funkcji. Nazwę to po prostu strażnikiem i znowu, jak widać, nie jest to specyficzne dla integers - możesz zrobić bardziej nieprzezroczyste typy i użyć tego ponownie.
type guard = <A>(f: (...ns: Array<A>) => A, ...ns: Array<A>) => A
const guard: guard = (f, ...ns) => f(...ns)
Jeśli spróbujesz to nazwać za pomocą number
const bad: integer = guard((a, b) => a + b as integer, myCoolInteger, 10)
pojawi się błąd jak poniżej
Argument of type '10' is not assignable to parameter of type 'integer'.
Type '10' is not assignable to type '{ readonly [TAG]: unique symbol; }'.(2345)
Zauważ, że nie wymuszasz tutaj zwracanego typu (ponieważ musisz go użyć as integer), a niektóre operatory, takie jak /, zwracają liczby zmiennoprzecinkowe, więc prawdopodobnie nadal chcesz sprawdzić w czasie wykonywania lub dodać a Math.rounddo wyspecjalizowanej wersji guard, ale to przynajmniej upewnić się, że nie próbujesz użyć dwóch odrębnych typów numerycznych razem - wyobraź sobie, że masz GBPa USDi spróbuj dodać te, które nie mogą być, co zamierzał.