Here's a query for you: AppendToObject. When I first tackled this question, my initial instinct was to utilize type intersection like so:
type AppendToObject<T, U extends PropertyKey, V> = T & {[P in U]: V}
Unfortunately, this solution did not pass the test cases provided.
type test1 = {
key: 'cat'
value: 'green'
}
type testExpect1 = {
key: 'cat'
value: 'green'
home: boolean
}
type test2 = {
key: 'dog' | undefined
value: 'white'
sun: true
}
type testExpect2 = {
key: 'dog' | undefined
value: 'white'
sun: true
home: 1
}
type test3 = {
key: 'cow'
value: 'yellow'
sun: false
}
type testExpect3 = {
key: 'cow'
value: 'yellow'
sun: false
moon: false | undefined
}
// reference from
// https://github.com/type-challenges/type-challenges/blob/main/utils/index.d.ts
type Equal<X, Y> =
(<T>() => T extends X ? 1 : 2) extends
(<T>() => T extends Y ? 1 : 2) ? true : false
type Expect<T extends true> = T
type cases = [
Expect<Equal<AppendToObject<test1, 'home', boolean>, testExpect1>>,
Expect<Equal<AppendToObject<test2, 'home', 1>, testExpect2>>,
Expect<Equal<AppendToObject<test3, 'moon', false | undefined>, testExpect3>>,
]
Subsequently, I switched to the iteration approach, which proved successful in passing all the tests.
type AppendToObject<T, U extends PropertyKey, V> = {[P in U | keyof T ]: P extends keyof T ? T[P] : V}
I couldn't identify any issues with the intersection method since specifying an extra argument is mandatory when typing an object with it. Perhaps the failure lies within the implementation of Equal
? Or could there be other subtleties between these two approaches that have eluded me?