-
-
Notifications
You must be signed in to change notification settings - Fork 146
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 add union type to object values #121
Comments
Hey @dsernst, There are a few ways to do this.
import {A, O} from 'ts-toolbelt'
type Omega = {
foo: number
bar: string
baz: string[]
}
type SomeType = 'hello'
// Pick the solution you prefer the most
type mapped0 = O.Update<Omega, A.Key, A.x | SomeType>
type mapped1 = O.Update<Omega, O.Keys<O>, A.x | SomeType> Update allows one to update existing values, or create new fields, and use the
type Mapper<O extends object, A> = {
[K in keyof O]: O[K] | A
}
type Omega = {
foo: number
bar: string
baz: string[]
}
type SomeType = 'hello'
type mapped0 = Mapper<Omega, SomeType>
import {A, O} from 'ts-toolbelt'
type Omega = {
foo: number
bar: string
baz: string[]
}
type SomeType = 'hello'
type mapped0 = O.Unionize<Omega, {[K in A.Key]: SomeType}>
Hope this helped, do not hesitate to ask more questions. Cheers |
Brilliant, thank you! You are a wizard 🧙♂️ |
It's only my pleasure! If any help is needed on your related issue, please ask :) |
@pirix-gh what if you only want it to apply to certain types of fields, for example, only to number fields? |
Hola @nandorojo, You would do this thanks to import {A, O} from 'ts-toolbelt'
type Omega = {
foo: number
bar: string
baz: string[]
} | {
foo: 42
bar: number
baz: string
qux: boolean | number
}
type SomeType = 'update' type test0 = O.Update<
Omega,
O.SelectKeys<Omega, number>,
A.x | SomeType
> // this uses 'extends->' by default
type test1 = O.Update<
Omega,
O.SelectKeys<Omega, number, 'contains->'>, // we select the fields that can contain `number`
A.x | SomeType
>
type test2 = O.Update<
Omega,
O.SelectKeys<Omega, number, '<-contains'>, // we select `number` that can contain the fields
A.x | SomeType // ^^^^^ no worries, I'll explain what this means
> Before I start explaining all the things in detail, let's explain what we did here above:
In this example, we made use of type A = 1
type B = 1 | 2
type test3 = A.Contains<A, B> // False // Equivalent to `contains->`
type test4 = A.Contains<B, A> // True // Equivalent to `<-contains` Moving the arrow to the other side causes the comparison to happen the other way around. And this is true for all the comparison operators (Extends, Implements, Contains, Equals): type test5 = A.Is<A, B, 'contains->'> // False // Equivalent to `A.Contains<A, B>`
type test6 = A.Is<A, B, '<-contains'> // True // Equivalent to `A.Contains<B, A>` Thanks to this, you can effectively compare the fields of an object to a type from left to right, or from right to left ( type test7 = O.SelectKeys<Omega, number, 'contains->'> How does type test8 = O.SelectKeys<Omega, number, '<-contains'> Then the question will be more like "Does the type test1 = O.Update<
Omega,
O.SelectKeys<Omega, number, 'contains->'>, // we select the fields that can contain `number`
A.x | SomeType
>
// This one will not let stuff like `boolean | number` pass, because `boolean | number` cannot contain `number`
type test2 = O.Update<
Omega,
O.SelectKeys<Omega, number, '<-contains'>, // we select `number` that can contain the fields
A.x | SomeType
>
// This will let stuff like `boolean | number` pass, because `number` can contain `boolean | number` Ok this was a bit of an advanced course, but you asked for it! Let me know if you have any questions. As a takeaway, you can take a look at the other matching operators. Cheers |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
🤔 Question
Given an object type like:
How could I transform all of the values to also accept another type, e.g.:
It's easy if the type is manually defined, as above.
But I'd like to make this into a transforming utility type for a library, with arbitrary objects passed in.
E.g.
is equivalent to:
Is this
AcceptSomeType<T>
function possible?Sort of like
mapValues
in Lodash. I see O.MergeUp can sort of do something like this, but I'm looking for it to work with any object shape passed in, not just specified keys.(See nandorojo/swr-firestore#21 for specific use-case)
Search tags, topics
#typescript #union #type #mapValues
The text was updated successfully, but these errors were encountered: