追求我的打字稿冒险,我确实找到了一个新的障碍。 我正在尝试为我的项目定义一个配置/选项验证器,但出现错误。一切正常(所有const等中的键入都是正确的。)期望突出显示的错误。而且我看不到我的错误^^
我确实有一个基于几个子类别的config对象,还有一个验证器对象,如果提出了建议,则该对象将使用其中的一些类别来验证它们。
当我在构建器函数的缩减程序中提取验证器(作为val)和选项(作为opt)时,当我尝试在opt上实际使用val时,那些选项已正确转换,这使我感到失望错误“类型缺少呼叫签名” (详细的打字稿消息位于代码结尾)
// the option interface
interface Options {
catA?: {optA1?: string, optA2?: number},
catB?: {optB1?: RegExp, optB2?: number},
catC?: {optC1?: string, optC2?: string},
}
// the default config
const Config: Options = {
catA: {optA1: 'x', optA2: 3 },
catB: {optB1: /abc/, optB2: 2 },
catC: {optC1: 'abc', optC2: 'a'},
}
// a keys helper function to get valid interface keys array as result
const _keys = <T extends {}>(o: T): (keyof T)[] =>
Object.keys (o) as (keyof T)[]
// a validator object that takes only keys of options and returns a
// predicate for some of them
const Validators: {
[P in keyof Options]: (x: Partial<Options[P]>) => boolean
} = {
catA: ({optA1, optA2}) =>
optA1 === undefined || optA1.length === 1 &&
optA2 === undefined || optA2 > 0,
catB: ({optB1, optB2}) =>
optB1 === undefined || optB1.flags.indexOf ('i') >= 0 &&
optB2 === undefined || optB2 > 0,
}
const builder = <T>(opts: Options) => {
// builds the config
const config = _keys (opts).reduce((conf, key) => {
const opt = opts[key]
// retrieve the validator for that key and if non provided
// builds it as () => true
const val = Validators[key] || (() => true)
if (!opts[key]) return conf
if (!val(opt)) throw Error('You have an error in option')
// ^^^^^^^^ => ts error: see comment below
return {...conf, [key]: opts[key]}
}, Config)
return (data: T) => {
// do something with data and config
}
}
// detailed error is:
// [ts] Cannot invoke an expression whose type lacks a call signature.
// Type '((x: Partial<{ optA1?: string; optA2?: number; }>) => boolean) |
// ((x: Partial<{ optB1?: RegExp; optB2?: number; }>) => boolean) |
// ((x: Partial<{ optC1?: string; optC2?: string; }>) => boolean)'
// has no compatible call signatures.
// const val: ((x: Partial<{
// optA1?: string;
// optA2?: number;
// }>) => boolean) | ((x: Partial<{
// optB1?: RegExp;
// optB2?: number;
// }>) => boolean) | ((x: Partial<{
// optC1?: string;
// optC2?: string;
// }
可能微不足道,如果很抱歉询问,在任何情况下都感谢您的阅读,如果有人可以指出我的错误,将不胜感激;)
谢谢 塞巴