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

Relaterede artikler