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