Skip to content

Instantly share code, notes, and snippets.

@fabiosantoscode
Last active January 22, 2023 22:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fabiosantoscode/9ccbf3f02732de6cf5954d5a63600f89 to your computer and use it in GitHub Desktop.
Save fabiosantoscode/9ccbf3f02732de6cf5954d5a63600f89 to your computer and use it in GitHub Desktop.
type MyTypeNames = {
'string': string,
'number': number,
}
type MyKey = {
readonly type: keyof MyTypeNames
readonly name: string
}
type MyKeys = ReadonlyArray<MyKey>
type AsOne<KeyArr extends MyKeys> =
KeyArr extends readonly [
{ readonly type: infer GivenType extends keyof MyTypeNames, name: (infer Name extends string) },
...infer RestKeys extends MyKeys
]
// We have a [{ type, name }, ...RestKeys]. Generate 1-key object and recurse to rest
? { [name in Name]: MyTypeNames[GivenType] } & AsOne<RestKeys>
: KeyArr extends readonly []
? {}
: 'this type should not be reached because KeyArr is always an array'
const xx = [{
type: 'string',
name: 'firstName'
}, {
type: 'string',
name: 'lastName'
}, {
type: 'number',
name: 'age'
}] as const
const x: AsOne<typeof xx> = {
firstName: 'somestr',
lastName: 'otherstr',
age: 123
}
const str = Symbol('MyType.String')
const num = Symbol('MyType.Number')
type MyKeys = ReadonlyArray<{
readonly type: typeof str
readonly name: string
} | {
readonly type: typeof num
readonly name: string
}>
const xx = ([{
type: str,
name: 'firstName'
}, {
type: str,
name: 'lastName'
}, {
type: num,
name: 'age'
}]as const) satisfies MyKeys
type AsOne<KeyArr extends MyKeys> = KeyArr extends readonly [infer T, ...infer T2 extends MyKeys]
? (
// We have a [T, ...T2]. Look at T and generate the correct one-key object
T extends { readonly type: typeof str, name: (infer Name extends string) }
? ({ [name in Name]: string } & AsOne<T2>) :
T extends { readonly type: typeof num, name: (infer Name extends string) }
? ({ [name in Name]: number } & AsOne<T2>)
: 'not sure what <type> is'
) : KeyArr extends readonly []
? {}
: 'this type should not be reached because KeyArr is always an array'
const x: AsOne<typeof xx> = {
firstName: 'somestr',
lastName: 'otherstr',
age: 123
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment