130. 嵌套对象变为唯一的类型
困难
TypeScript 有结构类型系统,但有时你希望一个函数只接受一些预定义的唯一对象,而不是接受任何具有所需字段的对象。
实现一个高级工具类型 DeepObjectToUniq<O>
,它接受一个对象 O
,并将该对象以及其中所有深度嵌套的对象变为唯一类型,同时保持对象的所有字符串和数字键,以及这些键上属性的值。
要求:
- 原始类型和结果类型必须是互相可赋值的,但它们不能是完全相同的。
- 嵌套对象的值需要在转换时被保持一致。
例子:
import { Equal } from '@type-challenges/utils'
type Foo = { foo: 2; bar: { 0: 1 }; baz: { 0: 1 } }
type UniqFoo = DeepObjectToUniq<Foo>
declare let foo: Foo
declare let uniqFoo: UniqFoo
uniqFoo = foo // ok
foo = uniqFoo // ok
type T0 = Equal<UniqFoo, Foo> // false
type T1 = UniqFoo['foo'] // 2
type T2 = Equal<UniqFoo['bar'], UniqFoo['baz']> // false
type T3 = UniqFoo['bar'][0] // 1
type T4 = Equal<keyof Foo & string, keyof UniqFoo & string> // true