Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

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

How to negate multiple numbers at once? #106

Closed
kripod opened this issue Apr 10, 2020 · 11 comments
Closed

How to negate multiple numbers at once? #106

kripod opened this issue Apr 10, 2020 · 11 comments
Assignees
Labels
bug Something isn't working question More info is requested wiki It's nice to learn stuff
Projects

Comments

@kripod
Copy link

kripod commented Apr 10, 2020

🤔 Question

Describe your question

I am trying to negate the keys of an object type. Currently, I'm trying with the following approach:

import { Number } from 'ts-toolbelt';

const obj = {
  0: 0,
  '1px': '1px',
  1: '0.25rem',
  2: '0.5rem',
};

let newObj: Number.Negate<Number.NumberOf<Extract<keyof typeof obj, number>>>;

Unfortunately, newObj is shown as a string instead of '0' | '-1' | '-2'.

Search tags, topics

negate, multiple, inference

@millsp millsp self-assigned this Apr 10, 2020
@millsp millsp added question More info is requested wiki It's nice to learn stuff bug Something isn't working labels Apr 10, 2020
@millsp millsp added this to To do in Board via automation Apr 10, 2020
@millsp
Copy link
Owner

millsp commented Apr 10, 2020

Hey @kripod this is the right way to do it! It's my fault, there is a bug 🐛.

@millsp
Copy link
Owner

millsp commented Apr 10, 2020

The fix will be out in minutes. Sorry about this :)

Here's another way to write it:

const obj = {
    0    : 0,
    '1px': '1px',
    1    : '0.25rem',
    2    : '0.5rem',
}

type Nbrs = Number.Negate<Number.NumberOf<keyof typeof obj & number>>

@kripod
Copy link
Author

kripod commented Apr 10, 2020

Fantastic, thank you! That was very quick.

@kripod
Copy link
Author

kripod commented Apr 10, 2020

Is it possible to negate the '1px' literal somehow, resulting in '-1px'? I was searching through TypeScript issues but found no proper solution.

@millsp
Copy link
Owner

millsp commented Apr 10, 2020

Pleasure! No it is not possible is pure ts, but we could build a map for pixels to enable this. If you look at how I've built operations on Number, it uses a Map to know which number is next or previous. So we could use such a map to do this with px. https://github.com/pirix-gh/ts-toolbelt/blob/master/src/Iteration/IterationOf.ts

If you are OK having a limitation that is from '-40px' to '40px'. This is the limitation we have for Number today as recursive (iteration) types (Minus...) cannot recurse infinitely. But nothing prevents you from adding more (than -40, 40) if you just plan to use it with Negate.

@kripod
Copy link
Author

kripod commented Apr 10, 2020

Wonderful 😲
Thanks for spending time to explain the details!

@millsp
Copy link
Owner

millsp commented Apr 10, 2020

Let me know if you need help to integrate such a feature, I didn't actually go very much in detail. Don't hesitate to contact me via gitter or open another issue.

I speculated many times that I should give the possibility to pass custom number maps (like pixels, or percents). I could implement this if you want. From there on, any custom map could be passed.

@millsp millsp closed this as completed Apr 10, 2020
Board automation moved this from To do to Done Apr 10, 2020
@kripod
Copy link
Author

kripod commented Apr 10, 2020

I'd highly appreciate if you could implement the ability to use custom maps, so project maintainers wouldn't have to copy a lot of boilerplate code, but would have a reusable, tested solution available.

By the way, I would use this for a new CSS-in-JS library with customizability, type-safety and performance in mind.

@millsp
Copy link
Owner

millsp commented Apr 10, 2020

Yo @kripod the new mapping system is on the way. You can now use pixel maps and perform math operations on it. It enabled considerable optimizations as well as more flexibility. So you can get started with pixel math!

If you need an example, please take a look at the tests https://github.com/pirix-gh/ts-toolbelt/blob/master/tst/Number.ts

I'll take a look to optimize Negate a bit later 😉 that should be fairly easy.

cc @tonivj5

@kripod
Copy link
Author

kripod commented Apr 10, 2020

Awesome job, thank you!

Unfortunately, I need to negate values from 0–64, so I opted for a custom solution until a more optimized version is available.

@millsp
Copy link
Owner

millsp commented Apr 10, 2020

You can use it now, it's been fixed. New limits are from -100 to 100 and with pixels too:

import {N, M} from 'ts-toolbelt'

type test0 = N.Negate<'100px', 's', M.Iteration.Pixel>

Repository owner locked and limited conversation to collaborators Feb 2, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
bug Something isn't working question More info is requested wiki It's nice to learn stuff
Projects
Board
  
Done
Development

No branches or pull requests

2 participants