需要类型操作方面的帮助。我有这个界面
interface IFormData<Inputs> {
data: Inputs;
transformData?: (data: Inputs) => <Result of data transformation>;
getData?: (values: Inputs or "Result of data transformation") => {...}
}
请注意,
transformData
可以作为函数传递,也可以不传递,这是一个可选参数。
如何实现,以便在传递
transformData
函数时,我们改变getData(values: ...)
中的类型?
界面功能
function transformer<T>({
getData,
transformData,
data
}: IFormData<T>) {
if(getData) {
if(transformData) {
getData(transformData(data)) // something to do
} else {
getData(data) // something to do
}
}
}
示例:
与
transformData
:
transformer({
data: {
first_name: "",
last_name: "string",
age: 34
},
transformData: (data) => {
return {
fullname: data.first_name + " " + data.last_name,
age: data.age
}
},
getData(values) {
"values" must be {
fullname: string;
age: number
}
}
})
没有
transformData
:
transformer({
data: {
first_name: "John",
last_name: "Makeev",
age: 34
},
getData(values) {
"values" must be {
first_name: string;
last_name: string
age: number
}
}
})
Result 是一个接口,可以帮助我执行正确的函数类型
为了使其正常工作,您的
IFormData
类型需要在 I
输入的 data
类型和 R
返回类型的 transformData
类型中均为 generic:
interface IFormData<I, R> {
data: I;
transformData?: (data: I) => R,
getData?: (values: R) => any;
}
那么你的
transformer
函数必须同样通用。您可以为
R
提供 I
的 默认类型参数,以便当 TypeScript 无法从函数输入推断 R
时,它会回退到 I
。 这样,省略 transformData
的调用将获得此默认值,然后 getData
将根据需要将 I
作为输入类型:function transformer<I, R = I>({
getData,
transformData,
data
}: IFormData<I, R>): void;
让我们测试一下。首先,当我们经过
transformData
时:
transformer({
data: {
first_name: "",
last_name: "string",
age: 34
},
transformData: (data) => {
return {
fullname: data.first_name + " " + data.last_name,
age: data.age
}
},
getData(values) {
/* (parameter) values: {
fullname: string;
age: number;
} */
}
})
看起来不错。这里
data
的
transformData
参数被上下文类型化为来自
I
属性类型的 {first_name: string, last_name: string, age: number}
类型 data
。并且 values
的 getData
参数根据上下文类型为 R
返回类型的 {fullname: string, age: number}
类型 transformData
。然后,不带transformData
打电话:
transformer({
data: {
first_name: "John",
last_name: "Makeev",
age: 34
},
getData(values) {
/* (parameter) values: {
first_name: string;
last_name: string;
age: number;
} */
}
})
这个看起来也不错。
values
的
getData
参数的类型已根据上下文从 {first_name: string, last_name: string, age: number}
的默认类型参数中输入为 R
,这与 I
相同,后者是从 的类型推断出来的data
财产。Playground 代码链接