Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript type to prevent division by 0

I am creating a calculation system for training purpose with typescript and I get a typing error during division.

Do you have any idea how to solve it?

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()

I get this error : The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.(2363)

like image 911
Rémi Bernard Avatar asked Jan 21 '26 06:01

Rémi Bernard


1 Answers

Here you have very simple implementation:

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`

Playground

b expected to be only literal number. It can't event be some variable with type of number because you don't know the value in runtime.

Let's proceed wot your example:

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

It is impossible in TypeScript to overload division operator / like in F#.

Hence, you need to create an extra function for division.

Num2 is infered number from b variable. If it is 0, NonZero returns never and the whole b argument becomes Variable<never>. SInce never is unrepresentable, you are getting error. Playground

like image 163
captain-yossarian Avatar answered Jan 22 '26 19:01

captain-yossarian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!