[英]TypeScript: in recursive type, extra props allowed to be assigned in object declaration only
当使用以下递归类型创建对象时,允许在创建对象时(但不是之后)以某种方式添加类型中不存在的额外键。 关于为什么会这样的任何想法?
type WithChildProps<Props, ChildProps> = Props & { __childProps__: ChildProps };
type WrappedProps<Props extends Record<string, any>, WrapperPropsTuple extends any[]> = WrapperPropsTuple extends [infer ParentProps, ...infer ChildProps]
? ChildProps extends []
? WithChildProps<ParentProps, Props>
: WithChildProps<ParentProps, WrappedProps<Props, ChildProps>>
: string;
type ObjTuple = [
{ prop1: string },
{ prop2: string },
{ prop3: string },
];
type ObjProps = { mainProp: string };
type ObjWrappedProps = WrappedProps<ObjProps, ObjTuple>;
const obj: ObjWrappedProps = {
prop1: 'allowed',
__childProps__: {
prop2: 'allowed',
__childProps__: {
prop3: 'allowed',
extraProp: 'why is this allowed?', // Should error but doesn't
__childProps__: {
mainProp: 'allowed',
extraProp: 'and this also?', // Should error but doesn't
},
},
},
};
// Errors as expected
obj.extraProp = 'expected error';
obj.__childProps__.__childProps__.extraProp = 'expected error';
虽然我无法解释这种行为,但我可以为您提供有效的实用程序类型。
考虑这个例子:
type ObjTuple = [
{ prop1: string },
{ prop2: string },
{ prop3: string },
];
type ObjProps = { mainProp: string };
type Key = '__childProps__';
type Builder<
Tuple extends any[],
Level extends number[] = [],
Result = {}> =
Level['length'] extends Tuple['length']
? Result & ObjProps
: Tuple[Level['length']] & {
[Prop in Key]:
Builder<Tuple, [...Level, 1], Result>
}
// ok
const test: Builder<ObjTuple> = {
prop1: 'allowed',
__childProps__: {
prop2: 'allowed',
__childProps__: {
prop3: 'allowed',
__childProps__: {
mainProp: 'allowed',
},
},
},
};
const test2: Builder<ObjTuple> = {
prop1: 'allowed',
__childProps__: {
prop22: 'allowed', // expected error
__childProps__: {
prop3: 'allowed',
__childProps__: {
mainProp: 'allowed',
},
},
},
};
const test3: Builder<ObjTuple> = {
prop1: 'allowed',
__childProps__: {
prop2: 'allowed',
__childProps__: {
prop3: 'allowed',
__childProps__: {
mainProp2: 'allowed', // expected error
},
},
},
}
Builder
- 仅迭代一个属性__childProps__
而Level
元__childProps__
度小于原始元组ObjTuple
。 IF长度等于-返回Result
合并ObjProps
,否则:合并prop
从通过索引元组Tuple[Level['length']]
通过递归迭代__childProps__
。
您可能已经注意到,我每次都将Level
tuple 增加1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.