繁体   English   中英

TypeScript union 作为函数参数

[英]TypeScript union as function parameter

我有一个应用程序,我在其中使用 json 结构来定义表的列。

每列都有一个keylabel属性以及一个可选的transformFunc属性,该属性采用一个函数来转换要在列中显示的数据。

这是Column的类型:

type Column = {
  key: string
  label: string
  transformFunc?: (value: string | number | Date) => string
};

transformFuncstringnumberDate作为参数。 但是,我无法以这种方式正确输入:

const col: Column = {
  key: 'date',
  label: 'Date',
  transformFunc: (value: string) => value.substring(0, 5)  // TS2322: Type '(value: string) => string' is not assignable to type '(value: string | number | Date) => string'
}

我该如何解决这个问题?

我研究了泛型,但我不知道如何做到这一点。

以一般方式

type Column<T extends string | number | Date> = {
  key: string
  label: string
  transformFunc?: (value: T) => string
};

const col: Column<string> = {
  key: 'date',
  label: 'Date',
  transformFunc: (value) => value.substring(0, 5)
}

由于您的类型定义, transformFunc必须接受联合的所有类型,因此您不能创建一个带有transformFunc的 Column 只接受一个。

如果您知道特定列将包含什么类型的数据,则可以在函数中使用类型断言:

const col: Column = {
  key: 'date',
  label: 'Date',
  transformFunc: (value: string | number | Date) =>
    (value as string).substring(0, 5)
}

或者,如果您不想使用泛型,则联合应该在函数范围之外

type Column = {
  key: string
  label: string
  transformFunc?: 
    ((value: string) => string) | 
    ((value: number) => string) | 
    ((value: Date) => string)
};

const col: Column = {
  key: 'date',
  label: 'Date',
  transformFunc: (value: string) => value.substring(0, 5)
}

或者,如果您想根据 transformFunc 的值推断类型,您可以使用辅助函数

type ColumnGeneric<T extends string | number | Date> = {
  key: string
  label: string
  transformFunc?: (value: string | number | Date) => string
}

const columnInferenceBuilder = <
  _ extends ColumnGeneric<FunctionProp>, 
  FunctionProp extends string | number | Date
>(o: {
  key: string;
  label: string;
  transformFunc: (value: FunctionProp) => string
}) => o

const inferredColumn = columnInferenceBuilder({
  key: 'date',
  label: 'Date',
  transformFunc: (value: string) => 'foobar',
})

如果您有一个额外的value属性对应于 transformFunc 参数(或以其他方式与之相关以区分),则此模式可能更有用

// imagine its imported
const importedData = {
  key: 'foo',
  label: 'Foo',
  value: 0
} as const

const inferredColumn2 = columnInferenceBuilder2({
  ...importedData,
  transformFunc: (value) => 'foobar',
  //   ^? (value: 0) => string
})

在 TS Playground 上查看这些示例

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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