推断类型中函数的返回类型并在类型本身中使用返回类型

问题描述 投票:0回答:1

我正在编写一些将用于 React 中的表组件的类型,但遇到了一些问题。

我想将数据提供给组件,然后推断数据类型以用于某些不同的目的。当我引入行格式化程序时,问题就出现了,它将修改数据并返回新类型。

我已经大大简化了类型来说明问题:

type Props<TRow, TFormattedRow> = {
  data: TRow[]
  getRow?: (row: TFormattedRow) => void
  rowFormatter: (row: TRow) => TFormattedRow
}

function createProps<TRow, TFormattedRow>(props: Props<TRow, TFormattedRow>) {
  return props
}

使用

createProps
函数时,通过在
row
中明确指定
rowFormatter
的类型,一切正常 -
rowFormatter
formattedRow
正确推断为
{ id: string, name: string, count: number }

createProps({
  data: [
    { id: '1', name: 'Mangus Karlsson', count: 4 },
    { id: '2', name: 'Elsa Nyström', count: 6 },
    { id: '3', name: 'Bengt Blyertz', count: 8 },
  ],
  // getData is infers the formatted row type correctly as { id: string, name: string, count: number }
  getRow: (formattedRow) => console.log(formattedRow),
  rowFormatter: (row: { id: string, name: string, count: number }) => {
    return { id: row.id, idAsNumber: parseInt(row.id) }
  },
})

尽管如此,当未显式设置

rowFormatter
的参数时,
getRow
会将
formattedRow
推断为
unknown
:

createProps({
  data: [
    { id: '1', name: 'Mangus Karlsson', count: 4 },
    { id: '2', name: 'Elsa Nyström', count: 6 },
    { id: '3', name: 'Bengt Blyertz', count: 8 },
  ],
  // formattedRow is infered as unknown when not explicitly typing the argument of rowFormatter
  getRow: (formattedRow) => console.log(formattedRow),
  rowFormatter: (row) => {
    return { id: row.id, idAsNumber: parseInt(row.id) }
  },
})

有没有办法在不显式输入

rowFormatter
的参数的情况下解决这个问题?或者我在这里遗漏了一些基本的东西?

typescript generics type-inference
1个回答
0
投票

如果你把

rowFormatter
放在第一位,它就会起作用。 IE。编译器首先从该属性推断类型。

const test = createProps({
  data: [
    { id: '1', name: 'Mangus Karlsson', count: 4 },
    { id: '2', name: 'Elsa Nyström', count: 6 },
    { id: '3', name: 'Bengt Blyertz', count: 8 },
  ],
  rowFormatter: (row) => ({ id: row.id, idAsNumber: parseInt(row.id) }),
  getRow: (formattedRow) => console.log(formattedRow),
})

// inferred type:
// const test: Props<{
//     id: string;
//     name: string;
//     count: number;
// }, {
//     id: string;
//     idAsNumber: number;
// }>

打字稿游乐场

© www.soinside.com 2019 - 2024. All rights reserved.