打字稿,还有另一种缺少呼叫签名

时间:2018-10-01 12:01:58

标签: typescript types casting

追求我的打字稿冒险,我确实找到了一个新的障碍。 我正在尝试为我的项目定义一个配置/选项验证器,但出现错误。一切正常(所有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;
// }

可能微不足道,如果很抱歉询问,在任何情况下都感谢您的阅读,如果有人可以指出我的错误,将不胜感激;)

谢谢 塞巴

0 个答案:

没有答案