[英]Typescript use parameter type inference with defaults
I have this function as below that works well: 我有如下功能,效果很好:
function pickAttributes<K extends string, T> (e: Element, attrs: K[]): Record<K, string> {
return attrs.reduce((obj, key) => {
return {
...(obj as any),
[key]: e.getAttribute(key)
}
}, {})
}
I want to be able to have this function take an optional map function to convert the attributes to a different type. 我希望该函数可以使用可选的map函数将属性转换为其他类型。
function pickAttributes<K extends string, T> (e: Element, attrs: K[], mapFn?: (attr: null | string) => T): Record<K, T> {
if (!mapFn) mapFn = x => String(x)
return attrs.reduce((obj, key) => {
return {
...(obj as any),
[key]: mapFn(e.getAttribute(key))
}
}, {})
}
However i get this error 但是我得到这个错误
TS2322:
Type '(x: string | null) => string' is not assignable to type '((attr: string | null) => T) | undefined'.
Type '(x: string | null) => string' is not assignable to type '(attr: string | null) => T'.
Type 'string' is not assignable to type 'T'.
I get a similar error if i try to use a default parameter. 如果我尝试使用默认参数,则会收到类似的错误。
The changed function seems to work as expected without trying to add a default 更改后的功能似乎可以正常运行,而无需尝试添加默认值
function pickAttributes<K extends string, T> (e: Element, attrs: K[], mapFn?: (attr: null | string) => T): Record<K, T> {
return attrs.reduce((obj, key) => {
return {
...(obj as any),
[key]: e.getAttribute(key)
}
}, {})
}
First: I'm not sure what could extend string, so I would drop the generic parameter K. 首先:我不确定什么可以扩展字符串,所以我将删除通用参数K。
But anyway: you want your return type to vary, based on the presence of the mapFn argument. 但是无论如何:您希望您的返回类型根据mapFn参数的存在而变化。 I would solve that by defining two overloads of the function.
我将通过定义函数的两个重载来解决这一问题。 And in the implementation, by using a union type
string | T
并且在实现中,通过使用联合类型
string | T
string | T
: string | T
:
function pickAttributes<K extends string>(e: Element, attrs: K[]): Record<K, string>;
function pickAttributes<K extends string, T> (e: Element, attrs: K[], mapFn: (attr: null | string) => T): Record<K, T>;
function pickAttributes<K extends string, T> (e: Element, attrs: K[], mapFn?: (attr: null | string) => T): Record<K, string | T> {
const fn = mapFn || (x => String(x));
return attrs.reduce((obj, key) => {
return {
...(obj as any),
[key]: fn(e.getAttribute(key))
}
}, {});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.