簡體   English   中英

如何檢查參數鍵是否以泛型類型列出?

[英]How to check that argument key is listed in generic type?

我剛開始在 ReactJS 中使用 TypeScript。 我想以這種方式聲明組件道具:

type TProps<T> = {
  data: {
    [key in T]: string // key should be listed on <T>
  }[]
  columns: {
    header: string
    name: // should be listed in <T>
  }[]
}
const Component = <T extends string[]>(props: TProps<T>) => {
  //some code here
}

在這種情況下,我收到一個關於T is not assignable to type 'string | number | symbol'的錯誤T is not assignable to type 'string | number | symbol' T is not assignable to type 'string | number | symbol'

我該如何定義它? 主要思想是用戶應該將列的名稱數組作為泛型傳遞,然后如果他傳遞名稱未在泛型中列出的組件的 props,它應該顯示錯誤。

例子:

const Table = <T extends string[]>(props) => {
  // code
}

// valid
Table<["name", "email"]>({
  data: [
    {
      name: "Alex",
      email: "alex@mail.com"
    },
    {
      name: "George",
      email: "george@mail.com"
    }
  ],
  columns: [
    {
      header: 'Name',
      dataColumn: 'name'
    },
    {
      header: 'E-Mail',
      dataColumn: 'email'
    }
  ]
});

// not valid
Table<["name", "email"]>({
  data: [
    {
      name: "Alex",
      email: "alex@mail.com"
    },
    {
      name: "George", // no email property
    }
  ],
  columns: [
    {
      header: 'Name',
      dataColumn: 'name'
    },
    {
      header: 'Phone',
      dataColumn: 'phone' // phone property not listed in generic type
    }
  ]
});

您需要向泛型類型參數添加約束,以便它只接受有效鍵類型的列表:

type TProps<T extends PropertyKey[]> = {
    data: {
        [key in T[number]]: string
    }[]
    columns: {
        header: string
        dataColumn: T[number]
    }[]
}

現在它的行為符合預期:

Table<["name", "email"]>({
    data: [
        {
            name: "Alex",
            email: "alex@mail.com"
        },
        {
            name: "George", // Property 'email' is missing in type ...
        }
    ],
    columns: [
        {
            header: 'Name',
            dataColumn: 'name'
        },
        {
            header: 'Phone',
            dataColumn: 'phone' // Type '"phone"' is not assignable to type '"name" | "email"'
        }
    ]
});

操場


我們使用T[number]來獲取允許鍵的聯合類型(數組/元組項類型


可以使用Record 實用程序簡化data定義

type TProps<T extends PropertyKey[]> = {
    data: Record<T[number], string>[]
    columns: {
        header: string
        dataColumn: T[number]
    }[]
}

暫無
暫無

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

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