提取函数的返回类型并按打字稿中的属性名称过滤

时间:2018-12-19 15:32:19

标签: typescript return-type conditional-types

我正在尝试确定具有特定属性名称的函数的返回类型,目的是筛选出没有此返回属性名称的任何函数。

为说明起见,假设我们具有以下函数对象:

export const StorageActions = {
  addFile: () => ({ type: 'ADD_FILE' }),
  deleteFile: () => {
    return () => {
      return null;
    };
  },
};
type StorageActionsTypes = typeof StorageActions;

借助ReturnType,我可以看到哪个函数的返回属性名称为'type':

enter image description here

要验证确实具有“类型”的返回属性名称的函数,我是 如下:

type filteredActions = { [K in keyof StorageActionsTypes]: 
    keyof ReturnType<StorageActionsTypes[K]> extends ('type') ?  'valid' : 'invalid'};

但结果出乎意料:

enter image description here

应该是:

interface filteredActions {
  addFile: 'valid';
  deleteFile: 'invalid';
}

我不正确地使用“扩展”吗?实现此目标的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

问题是您对never的解释。切勿按照PR所述:

  

never是每种类型的子类型,可以分配给每种类型。

这意味着type y = never extends 's' ? 'Y' : 'N'的类型将是'Y',因为never's'的子类型。

这里的简单解决方案是不使用keyof(对于函数来说,它将返回never,因此是上面的问题)

export const StorageActions = {
    addFile: () => ({ type: 'ADD_FILE' }),
    deleteFile: () => {
        return () => {
            return null;
        };
    },
};

type StorageActionsTypes = typeof StorageActions
type filteredActions = {
    [K in keyof StorageActionsTypes]:
        ReturnType<StorageActionsTypes[K]> extends { type: any } ? 'valid' : 'invalid'
}; // now  { addFile: "valid"; deleteFile: "invalid"; }