Typescript-type til at forhindre division med 0
Jeg laver et beregningssystem til træningsformål med TypeScript, og jeg får en typningsfejl under division.
Har du nogen idé om, hvordan man løser det?
type Variable = {
value: number
resolve: () => number
}
type NoZeroVariable = {
value: Omit<number, 0>
resolve: () => Omit<number, 0>
}
// then when I try to resolve the operation
a.resolve() / b.resolve()
Jeg får denne fejl: Højresiden af en aritmetisk operation skal være af typen 'any', 'number', 'bigint' eller en enum-type.(2363)
Svar #1
Her har du en meget simpel implementering:
type NonZero<T extends number> = T extends 0 ? never : number extends T ? never : T
const division = <
A extends number,
B extends number
>(a: A, b: NonZero<B>) =>
a / b
division(10, 2) // ok
division(10, 0) // error
const higherOrderFunction = (b: number) => division(10, b) // error, b is not verified
`NonZero` - expects a number. If number is has a literal representation like `1`,`2` or any other literal it returns this number, otherwise (if it is `0` or `number`) it returns `never`
Legeplads
b forventes kun at være et bogstaveligt tal. Det kan ikke engang være en variabel af typen number, fordi du ikke kender værdien under kørsel.
Lad os fortsætte med dit eksempel:
type Variable<N extends number> = {
value: N
resolve: () => number
}
type NonZero<T extends number> = T extends 0 ? never : number extends T ? never : T
const variableDivision = <
Num1 extends number,
Num2 extends number,
>(a: Variable<Num1>, b: Variable<NonZero<Num2>>) =>
a.resolve() / b.resolve()
variableDivision({ value: 42, resolve: () => 42 }, { value: 42, resolve: () => 0 }) // ok
variableDivision({ value: 42, resolve: () => 42 }, { value: 0, resolve: () => 0 }) // expected error
Det er umuligt i TypeScript at overbelaste divisionsoperatoren / som i F#.
Derfor skal du oprette en ekstra funktion til division.
Num2 er et udledt tal fra b-variablen. Hvis det er 0, returnerer NonZero never, og hele b-argumentet bliver Variable<never>. Da never ikke kan repræsenteres, får du en fejl. Playground
