无法在Typescript

时间:2019-02-02 15:18:30

标签: typescript

我具有以下功能:

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。是否有我可以使用类型参数的函数内施放任何语法?

3 个答案:

答案 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
    }