繁体   English   中英

TypeScript:在递归类型中,只允许在对象声明中分配额外的道具

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM