大家好。:)
作为这个问题的后续,我们有以下代码:
interface SubThing {
name: string;
}
interface Thing {
subThing: SubThing; // or any other property of type SubThing like in UpperThing
}
interface UpperThing {
thing: Thing
}
interface ThingMapA {
map: { thing: { subThing: { name : 'subThing name' } } };
}
interface ThingMapB {
map: { thing: { otherThing: { name : 'subThing name' } } };
}
class Handler<T extends Record<keyof T, Record<keyof T, Thing>>> {}
const handler = new Handler<ThingMapA>(); // error
const handler = new Handler<ThingMapB>(); // error
我喜欢Handler
接受任何具有UpperThing
类型属性(理想情况下至少有一个)的类,并且具有Thing
类型的任何属性(理想情况下至少有一个)。但ThingMap
不被识别。这会导致错误。有什么建议吗?😊
这是另一个基于@jcalz
方法的例子interface SubThing {
name: string;
}
interface Thing {
subThing: SubThing;
}
interface UpperThing {
thing: Thing
}
interface ThingMapA {
map: { thing: { subThing: { name: 'subThing name' } } };
}
interface ThingMapB {
map: { otherThing: { subThing: { name: 'subThing name' } } };
}
interface ThingMapC {
map: { thing: { otherSubThing: { name: 'subThing name' } } };
}
interface ThingMapD {
map: { otherThing: { otherSubThing: { name: 'subThing name' } } };
}
class Handler<T extends { [K in keyof T]: { [P in keyof T[K]]: Thing } }> { }
const handlerA = new Handler<ThingMapA>(); // okay
const handlerB = new Handler<ThingMapB>(); // okay
const handlerC = new Handler<ThingMapC>(); // error
const handlerD = new Handler<ThingMapD>(); // error
如果您需要约束类型T
,以便每个子属性都是类型SubThing
,那么您将需要编写涉及嵌套映射类型的适当深度的递归约束:
class Handler<T extends {
[K in keyof T]: {
[P in keyof T[K]]: {
[Q in keyof T[K][P]]: SubThing
}
}
}> { }
让我们测试一下:
const handlerA = new Handler<ThingMapA>(); // okay
const handlerB = new Handler<ThingMapB>(); // okay
const handlerC = new Handler<ThingMapC>(); // okay
const handlerD = new Handler<ThingMapD>(); // okay
const badhandler = new Handler<{
a: { b: { c: { name: "" } } },
d: { e: { f: { name: 123 } } } // error!
}>
// The types of 'd.e.f.name' are incompatible between these types.
看起来不错。
Playground链接到代码