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'
|
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<
|
export type Assign<
|
||||||
Shape extends object,
|
Shape extends object,
|
||||||
Defaults extends Pick<Required<Shape>, OptionalKeysOf<Shape>>,
|
Defaults extends Pick<Required<Shape>, OptionalKeysOf<Shape>>,
|
||||||
Obj extends 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 type { Assign } from '@/assign.js'
|
||||||
import { expect } from 'tstyche'
|
import { expect } from 'tstyche'
|
||||||
|
|
||||||
interface Person {
|
interface OptionsWithRequired {
|
||||||
name: string
|
name: string
|
||||||
|
tag?: string
|
||||||
age?: number
|
age?: number
|
||||||
}
|
relations?: Array<OptionsWithRequired>
|
||||||
|
|
||||||
interface Options extends Person {
|
|
||||||
relations?: Array<Person>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DefaultValues {
|
interface DefaultValues {
|
||||||
name: 'Max Mustermann'
|
tag: 'Max Mustermann'
|
||||||
age: 17
|
age: 17
|
||||||
relations: []
|
relations: []
|
||||||
}
|
}
|
||||||
|
|
||||||
expect<Assign<Options, DefaultValues, { name: 'Another Name' }>>().type.toBe<{
|
expect<Assign<OptionsWithRequired, DefaultValues, { name: 'Another Name' }>>().type.toBe<{
|
||||||
name: 'Another Name'
|
name: 'Another Name'
|
||||||
age?: 17
|
tag: 'Max Mustermann'
|
||||||
relations?: []
|
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'
|
name: 'Another Name'
|
||||||
age?: 18
|
tag: 'Max Mustermann'
|
||||||
relations?: []
|
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