feat(typescript-types): Remove optionality of keys in Assign
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
import type { OptionalKeysOf } from './optional-keys-of.js'
|
||||
|
||||
type GetNonOptionalValueAt<Obj, Key, Default> = Key extends keyof Obj
|
||||
? undefined extends Obj[Key]
|
||||
? Default
|
||||
: Obj[Key]
|
||||
: Default
|
||||
|
||||
export type Assign<
|
||||
Shape extends object,
|
||||
Defaults extends Pick<Required<Shape>, OptionalKeysOf<Shape>>,
|
||||
Obj extends Shape
|
||||
> = {
|
||||
[K in keyof Shape]: K extends keyof Obj ? Obj[K] : K extends keyof Defaults ? Defaults[K] : never
|
||||
[K in keyof Shape]-?: GetNonOptionalValueAt<Obj, K, K extends keyof Defaults ? Defaults[K] : never>
|
||||
}
|
||||
|
||||
@@ -1,29 +1,46 @@
|
||||
import type { Assign } from '@/assign.js'
|
||||
import { expect } from 'tstyche'
|
||||
|
||||
interface Person {
|
||||
interface OptionsWithRequired {
|
||||
name: string
|
||||
tag?: string
|
||||
age?: number
|
||||
}
|
||||
|
||||
interface Options extends Person {
|
||||
relations?: Array<Person>
|
||||
relations?: Array<OptionsWithRequired>
|
||||
}
|
||||
|
||||
interface DefaultValues {
|
||||
name: 'Max Mustermann'
|
||||
tag: 'Max Mustermann'
|
||||
age: 17
|
||||
relations: []
|
||||
}
|
||||
|
||||
expect<Assign<Options, DefaultValues, { name: 'Another Name' }>>().type.toBe<{
|
||||
expect<Assign<OptionsWithRequired, DefaultValues, { name: 'Another Name' }>>().type.toBe<{
|
||||
name: 'Another Name'
|
||||
age?: 17
|
||||
relations?: []
|
||||
tag: 'Max Mustermann'
|
||||
age: 17
|
||||
relations: []
|
||||
}>()
|
||||
|
||||
expect<Assign<Options, DefaultValues, { name: 'Another Name'; age: 18 }>>().type.toBe<{
|
||||
expect<Assign<OptionsWithRequired, DefaultValues, { name: 'Another Name'; age: 18 }>>().type.toBe<{
|
||||
name: 'Another Name'
|
||||
age?: 18
|
||||
relations?: []
|
||||
tag: 'Max Mustermann'
|
||||
age: 18
|
||||
relations: []
|
||||
}>()
|
||||
|
||||
interface Options {
|
||||
tag?: string
|
||||
age?: number
|
||||
}
|
||||
|
||||
expect<Assign<Options, DefaultValues, {}>>().type.toBe<{
|
||||
tag: 'Max Mustermann'
|
||||
age: 17
|
||||
}>()
|
||||
|
||||
interface SpecifiedOptions extends Options {}
|
||||
|
||||
expect<Assign<Options, DefaultValues, SpecifiedOptions>>().type.toBe<{
|
||||
tag: 'Max Mustermann'
|
||||
age: 17
|
||||
}>()
|
||||
|
||||
Reference in New Issue
Block a user