-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add math intrinsic types #48198
base: main
Are you sure you want to change the base?
Add math intrinsic types #48198
Conversation
The TypeScript team hasn't accepted the linked issue #26382. If you can get it accepted, this PR will have a better chance of being reviewed. |
may i understand the specific use case you wanna address? imho this might not be a case that TypeScript is designed to solve. |
Shouldn't LessThan return a boolean literal type instead of number/never? |
Two reasons it's a number:
That said, those two are the ones I am least sure about. I think something like what's suggested in #43505 would be far better. |
What about |
https://github.com/unional/type-plus/tree/main/ts/math |
499364f
to
6ebbc75
Compare
Updated this.
Implementing the previous type LessThan<M, N> = `${Subtract<M, N>}` extends `-${number}` ? M : never
type GreaterThan<M, N> = `${Subtract<N, M>}` extends `-${number}` ? M : never |
This could be useful for example for the quickjs-API. quickjs borrows error handling from the C API, and therefore values |
src/compiler/checker.ts
Outdated
return n; | ||
} | ||
|
||
function applyNumberMapping2(symbol: Symbol, a: NumberLiteralType, b: NumberLiteralType): Type { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is quite some code duplication, what do you think about for instance:
const MathArity2: Record<string, (a: number, b: number) => number> = {
Add : (a, b) => a + b,
Sub : (a, b) => a - b,
Mul : (a, b) => a * b,
Div : (a, b) => a / b,
Pow : (a, b) => a ** b,
Hypot: (a, b) => Math.hypot(a, b),
Min : (a, b) => Math.min (a, b),
Max : (a, b) => Math.max (a, b),
};
And MathArity1
could have exp
(E ** x
), sin
, cos
, tan
, abs
, round
, sqrt
and your Integer
(or just floor
to keep it in sync with JS?).
(MathArity0
would be simply constants like PI
and E
, probably just a constants in the d.ts
?)
@skeate Do you have any plans to merge it with latest changes? Otherwise this PR is amazing and I'm so happy I found it! |
I reintegrated this into the latest TS version (HEAD) and it still works like a charm, great work! Playing around with this is interesting and I came across this: type Add10<T extends number> = Add<T, 10>;
type Add20<T extends number> = Add<10, Add<10, T>>;
type tmpA = Add10<20>; // Outputs: 30
type tmpB = Add20<20>; // Outputs: 40 If you hover over Should something like |
😮 I'm surprised; the conflicts looked pretty severe so I thought it'd basically require reimplementing the whole PR. If you want, I think you could PR that to my fork and then it should show up here. Though I'm not very hopeful that this will actually get merged; it was more a proof of concept/learning exercise. I don't think that e.g. simplifying I'm not sure if the more floating-point-oriented types have much utility. Because of the inherent imprecision of floating point math, it doesn't seem like it belongs in the type system. I was hesitant to even include If you have a use case for them, though, I'd be interested to hear it |
526f96a
to
8517071
Compare
Co-authored-by: kungfooman <[email protected]>
@kungfooman thank you for your PR to bring it up to date. I hope you don't mind but I took the diff from microsoft/TypeScript:main and remade it as a single commit, just to avoid a gnarly history. I added you as a co-author in the commit message though. |
.. Didn't mean to un-draft this PR. Oops. |
Hello @skeate, thank you for your work which I find really great. Do you think you'll have time to finish your pull request soon? What can we do to help you? I'm really looking forward to using your new feature :) |
@toofff You can fix the unit tests and make a PR towards https://github.com/skeate/TypeScript/tree/main |
I'd like to give it a try, plus I've never worked in your repo before. I'll keep you posted. thank you for your comment @kungfooman |
Fixes #26382
With
intrinsic
types, it seemed like some simple type-level math would be a straightforward addition, so I wanted to try it out.This adds several new
intrinsic
types to perform numerical operations on number literal types:Integer<N>
callsMath.floor
onN
Add<M, N>
evaluates to M+NMultiply<M, N>
evaluates to M*NSubtract<M, N>
evaluates to M-NDivide<M, N>
evaluates to M/N (floating point division)(removed, see comment below)LessThan<M, N>
isM
if M < N, otherwisenever
(removed, see comment below)GreaterThan<M, N>
isM
if M > N, otherwisenever
The goal is to permit things like type-safe sized containers, beyond simple arrays/tuple-types, or anything else for which you might want to do some simple type-level math without having to resort to various hacky solutions (not that these are bad solutions, but they usually are hard to understand, are full of limitations, and make the typechecker do more work than should be necessary for this kind of thing).