簡體   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