这里你有非常简单的实现:
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`
操场 https://www.typescriptlang.org/play?target=8#code/C4TwDgpgBAcg9gOwFoQE5wDwBUoQB7AQIAmAzlAgK4C2ARmgHxQC8UO%20hJ5ADFAPwUIANzRQAXBRr1UuAkTJt%20gkTIlYAUJoDGiUsCjEAlkMOlDiFlAzqotqAEFZnBVTpoANDbsAhJ-PKu0uoMABQAhhL27lC0EvDIaJjeDACULAxetmFQAPQxmkYmZoghAIzc0QBMaTl5cADW6oWm5ghlFVDcNXlo6Kia6joIelAAFoYA5qNoAPKoxGgAYpQIWsCtliGxkm6oacxMzcVt5dG03biofWdQphRw%20iqGAGaGEMTqQA
b
预计只是字面数字。它不能是某个类型为number
因为你不知道运行时的值。
让我们继续你的例子:
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
在 TypeScript 中不可能重载除法运算符/
像F#
.
因此,您需要创建一个额外的除法函数。
Num2
是红外号码b
多变的。如果是0
, NonZero
回报never
和整个b
论证变成Variable<never>
. SInce never
是无法代表的,你会得到错误。操场 https://www.typescriptlang.org/play?#code/C4TwDgpgBAaghgJwJZwEYBsIB4ByUIAewEAdgCYDOUJArgLaoQIB8UAvFAN4CwAUFFABucdDQgAuKDj4CEECgHt0giVAAUASnataDJnwC%20fY71CQpCkgC0mCrABV8RUpWr1GLdlEeFi5KgAMUAD81BAqCFCSuh5Ofq6OoSThTFHeJnwAxpYUwEKIKBgQACJIgkgUSJZeWDJS9ACMcS5UMUwANHU49ABMzf5uegidvHXManCS8MhomLiNzO1QqFMFs9g4ljYIdt10PczMWmzMdXAAdHKKyhCaUAD0y5fySiqaJsIzRaXllZZqnHyolUABYeksrq9VHcTlAwVADEtAcJgZIwRCXjdJDDWEEDFp7o8FABrPifQqYH4VKokAFAsRo8FQSFY9THVjwxFcemqAIY64qbHsqB4gmPQiQTLEMj4BA7BAZXhAA