首页 > 解决方案 > 打字稿中有没有办法只允许除不返回布尔值的函数以外的任何东西?

问题描述

所以我遇到了一个问题,我有这样的功能:

function myFunc<T>(filterFnOrObj: T | (x: T) => boolean){
    if (typeof input === 'function') {
        someArray.filter(filterFnOrObj)
    } else {
        someArray.indexOf(filterFnOrObj)
    }
}

可能发生的情况是,如果有人传入一个不是真正过滤器函数的函数,代码会将其视为过滤器,因为我不知道返回类型。我也不想调用该函数并查看它是否返回布尔值。

我要做的是防止人们传入一个函数,但不是返回布尔值的函数。任何其他类型都可以。我知道条件类型,但我不知道如何使用它们来完成这个。

标签: typescript

解决方案


也许试试下面的代码。这里有 2 个主要组成部分:

  1. FilterWorthyfiltertype - 它可以防止您在编译时传递任何签名不适合谓词的函数
  2. isFilterWorthy是一个类型保护,它需要在运行时决定filter/indexOf
type FilterWorthy<T> = ((x: T) => boolean)
    | ((x: T, i: number) => boolean)
    | ((x: T, i: number, arr: T[]) => boolean)

function myFunc<T>(someArray: T[], filterFnOrObj: T | FilterWorthy<T>) {
    if (isFilterWorthy<T>(filterFnOrObj)) {
        someArray.filter(filterFnOrObj)
    } else {
        someArray.indexOf(filterFnOrObj)
    }
}

function isFilterWorthy<T>(x: T | FilterWorthy<T>): x is FilterWorthy<T> {
    return typeof x === 'function'
}

const isEven = (x: number): boolean => x % 2 === 0
const alwaysTrue = <T,>(x: T, i: number, arr: T[]): boolean => true
const returnsBooleanButWrongParams = (x: number, arr: number[]): boolean => true
const returnsNumber = (): number => 1
const returnsObj = (): Record<string, unknown> => ({})

myFunc([1, 2], isEven)                        // OK
myFunc(['a'], alwaysTrue)                     // OK
myFunc([1, 2], returnsBooleanButWrongParams)  // Error
myFunc([1, 2, 3], returnsNumber)              // Error
myFunc([{a: 1}, {b: 2}], returnsObj)          // Error


推荐阅读