【发布时间】:2021-12-19 19:40:53
【问题描述】:
在 vanilla JS 中,我可以编写如下代码:
function renderTextField(props) { }
function renderSelectField(props) { }
const fieldMapping = {
text: renderTextField,
select: renderSelectField,
};
function renderField(field) {
const renderFn = fieldMapping[field.type];
renderFn(field.data);
}
使用 2 种类型的字段只是为了保持示例的小,但是这段代码的好处是通用方法不需要知道字段的类型,它将决定委托给 @ 提供的映射987654323@.
我正在尝试在 TypeScript 中编写类似的东西。但我不知道如何让这些类型工作并仍然使用一个对象来提供type 和委托给的函数之间的映射。
我意识到我可以使用 switch 语句或条件而不是对象来映射事物,但如果可能的话,我更愿意这样做。
type TextFieldData = { value: string }
type TextField = { type: 'text', data: TextFieldData }
type SelectFieldData = { options: string[], selectedValue: string }
type SelectField = { type: 'select', data: SelectFieldData }
type FormField = TextField | SelectField
function renderTextField(props: TextFieldData) {}
function renderSelectField(props: SelectFieldData) {}
const fieldMapping = {
text: renderTextField,
select: renderSelectField,
}
// This won't work!
function renderFieldDoesNotWork(field: FormField) {
const renderFn = fieldMapping[field.type]
// Type 'TextFieldData' is missing the following properties from type 'SelectFieldData': options, selectedValue
renderFn(field.data)
}
// This works
function renderFieldWorks(field: FormField) {
if (field.type === 'text') {
const renderFn = fieldMapping[field.type]
renderFn(field.data)
} else if (field.type === 'select') {
const renderFn = fieldMapping[field.type]
renderFn(field.data)
}
}
【问题讨论】:
-
看起来像另一个问题要添加到一堆... TypeScript 缺乏对correlated record types 的良好支持,因此您可能需要使用类型断言。
标签: typescript