簡體   English   中英

React Typescript 組件的遞歸接口

[英]A recursive interface for a React Typescript component

該組件是一個面包屑,它必須接收一個對象作為道具,該對象包含一個標題和一個 url 以及一個選項子節點。 最大深度應該是 5,在這種情況下,這是一個道具示例:

myProps = {
            title: "level 1",
            url: "/",
            children: {
                        title: "level 2"
                        url: "/level2"
                        children: { 
                                    title: "level 3"
                                    url: "level2/level3"
                                    children: {
                                                title: "level 4"
                                                url: "level2/level3/level4"
                                                children: {
                                                            title: "level 5"
                                                            url: "/level2/level3/level4/level5"
                                                          }
                                               }
                                  }
                       }
          };

但它也可以減少嵌套,例如:

myProps = {
            title: "title1"
            url: "/"
            children: null
          }

界面應該是什么樣子的?

這樣對嗎?

export interface MyProps {
  title: string;
  url: string;
  children: MyProps;
}

你需要考慮那些沒有孩子的人,所以

export interface MyProps {
  title: string;
  url: string;
  children?: MyProps | null;
}

您的界面是一個好的開始! 如果我做對了, MyProps.children是可選的,對嗎? 在這種情況下,您可以像這樣聲明它:

export interface MyProps {
  title: string;
  url: string;
  children?: MyProps;
}

這允許您在聲明類型為MyProps的變量期間省略屬性children並顯式分配它undefined

const myProps: MyProps = {
  title: "title1",
  url: "/"
};

const otherProps: MyProps = {
  title: "title1",
  url: "/",
  children: {
    title: "title2",
    url: "/otherUrl"
  }
};

const yetOtherProps: MyProps = {
  title: "title1",
  url: "/",
  children: undefined
};

如果您預先知道嵌套屬性的數量,則可以使用此實用程序類型:

export interface MyProps {
  title: string;
  url: string;
  children: undefined;
}

type Recursive<
  Length extends number,
  Counter extends number[] = [],
  Result = MyProps
  > =
  (Length extends Counter['length']
    ? Result
    : {
      [Prop in keyof MyProps]:
      (Prop extends 'children'
        ? (Length extends [...Counter, 1]['length']
          ? Recursive<Length, [...Counter, 1], undefined>
          : Result | Recursive<Length, [...Counter, 1], Result>)
        : (Prop extends 'title'
          ? `${string} ${[...Counter, 1]['length'] extends string | number ? [...Counter, 1]['length'] : ''}`
          : MyProps[Prop])
      )
    })

const test0: Recursive<6> = { // ok
  title: `a 1`,
  url: 'string',
  children: {
    title: `a 2`,
    url: ' string',
    children: {
      title: `  3`,
      url: 'string',
      children: {
        title: ` 4`,
        url: 'string',
        children: undefined
      },
    },
  },
}

const test1: Recursive<6> = { // ok
  title: `a 1`,
  url: 'string',
  children: {
    title: `a 2`,
    url: ' string',
    children: {
      title: `  3`,
      url: 'string',
      children: {
        title: ` 4`,
        url: 'string',
        children: {
          title: ` 5`,
          url: 'string',
          children: {
            title: `6`,
            url: 'string',
            children: undefined
          },
        },
      },
    },
  },
}

const test2: Recursive<5> = {
  title: `a 1`,
  url: 'string',
  children: {
    title: `a 2`,
    url: ' string',
    children: {
      title: `  3`,
      url: 'string',
      children: {
        title: ` 4`,
        url: 'string',
        children: {
          title: ` 5`,
          url: 'string',
          children: { // expected error
            title: `6`,
            url: 'string',
          },
        },
      },
    },
  },
}

操場

解釋

Recursive parametersLength - 嵌套屬性Counter的數量 - 因為不可能在 TS 中進行數學運算,所以我使用元組並將長度每次增加 1 [...Counter, 1] Result - 直接 - 結果: D

它是如何工作的?

每一步都從LengthCounter['length']比較開始。 如果Counter['length']等於所需的嵌套屬性數量 - 返回Result

否則,每次循環遇到children屬性時,遍歷MyProps每個屬性結束 - 遞歸調用它並增加Counter

Recursive<5> - 意味着您最多可以聲明 5 個嵌套子項。 你可以少申報但不能多申報

我為title屬性添加了額外的邏輯。 每個title屬性都有自己的編號。

就這樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM