我具有以下功能:
const getDefaultFilterObjFromKeys:
<Key extends keyof FilterFields>(keys: Key[]) => IFiltersState<Key> =
(keys) => {
if (keys.length === 0){
throw Error("empty Arr")
}
const defaults = {}
Object.entries(_.pick(filterFields, keys)).forEach(
([key, filterField]) => {
defaults[key] = filterField.defaultVal
},
)
return defaults as IFiltersState<Key>
}
我收到一个错误,指出返回类型与定义的返回类型不匹配。我认为是这样,但打字稿有困难的时候认识的实际返回类型因各种原因(它无法识别的按键阵列不能为空,并且有一些计算和操作),所以要么忽略错误或要求铸造。我宁愿投,但为了投我需要能够使用的功能中的关键参数类型。尝试这样做时,出现错误Cannot find name Key
。是否有我可以使用类型参数的函数内施放任何语法?
答案 0 :(得分:2)
这是因为你的签名是语法是错误的,所以你结束了一个嵌套的箭头功能,Key
是的范围进行。除非您担心绑定,否则实际上不需要使用const = () =>
定义函数,因此可以使用function关键字使其更具可读性:
function getDefaultFilterObjFromKeys<Key extends keyof FilterFields>(keys: Key[]): IFiltersState<Key> {
if (keys.length === 0){
throw Error("empty Arr")
}
const defaults = {}
Object.entries(_.pick(filterFields, keys)).forEach(
([k, filterField]) => {
defaults[k] = filterField.defaultVal
},
)
return defaults as IFiltersState<Key>
}
如果您确实想使用const,则正确的签名语法为:
const getDefaultFilterObjFromKeys2 = <Key extends keyof FilterFields>(keys: Key[]): IFiltersState<Key> => {
if (keys.length === 0){
throw Error("empty Arr")
}
const defaults = {}
Object.entries(_.pick(filterFields, keys)).forEach(
([k, filterField]) => {
defaults[k] = filterField.defaultVal
},
)
return defaults as IFiltersState<K>
}
答案 1 :(得分:1)
@Robbie的回答和评论。
const function1: <I>(arg:I) => I = (arg) => {....}
const function2 = <I>(arg:I):I{...}
并不完全等效。区别之一是在函数2中,您可以在函数主体内使用type参数。为了在以第一种形式编写函数时能够使用类型参数,您必须将类型参数定义为函数本身的一部分。
const function1: <I>(arg:I) => I = <I>(arg:I) => {....}
这使我们的代码更加冗长,因此在这种情况下,人们可能更喜欢使用编写function2的形式。
答案 2 :(得分:1)
如果我是你,这就是我写的方式。您没有为我的请求提供答案(我已删除了该评论),因此我不得不在某些地方即兴创作。我删除了lodash,然后将Object.entries
替换为更简单的Object.keys
。
此外,根据我的经验,您应该始终将类型(接口)与实现分开。那就是我所做的。但是,这并不意味着您在实现部分中也不需要复制某些类型变量(Key
)。
您可能缺少的主要想法是:
您丢失了Key
是因为您在约束类型中定义了它,但没有在实现函数中定义它
const filterFields = {
foo: {
defaultVal: 123
}
}
type FilterFields = typeof filterFields
interface IFiltersState<K> = {
}
interface GetDefaultFilterObjFromKeys {
<Key extends keyof FilterFields>(keys: Key[]): IFiltersState<Key>
}
const getDefaultFilterObjFromKeys:
GetDefaultFilterObjFromKeys =
<Key extends keyof FilterFields>(keys: Key[]) => {
if (keys.length === 0) {
throw Error("empty Arr")
}
const defaults: {
[K in keyof FilterFields]: FilterFields[K]['defaultVal']
} = {} as any;
(Object.keys(filterFields) as Key[]).forEach(
key => {
if (!keys.includes(key)) {
return
}
defaults[key] = filterFields[key].defaultVal
},
)
return defaults
}