簡體   English   中英

為什么 TypeScript 將 function 的參數類型標記為“從不”

[英]Why does TypeScript mark the type of argument from function as 'never'

這是過濾器 function 和 function 本身的兩個簽名的聯合類型。

type Filter = {
  (arr: string[], f: (item: string) => boolean): string[]
  (arr: number[], f: (item: number) => boolean): number[]
}

let filter: Filter = (arr, func) => {
    let result = []
    for (let i in arr) {
        let item = arr[i]
        if (func(item)) {
            result.push(item)
        }
    }
    return result
}

編譯器將此參數作為聯合類型的 function 接受:

在此處輸入圖像描述

但是,在 function 內部它沒有並將參數item標記為never

在此處輸入圖像描述

問題是,如果將 function 鍵入為((item: string) => boolean) | ((item: number) => boolean) ((item: string) => boolean) | ((item: number) => boolean)沒有任何我們可以稱之為 function 的東西對於 function 簽名 ex 是安全的:

let fn: ((item: string) => boolean) | ((item: number) => boolean)
fn = Math.random() > 0.5 ? (i: string) => !!i.toUpperCase() : (i: number)=> !!i.toExponential()

fn(10) // Will fail if the function is the one that accepts strings
fn("") // Will fail if the function is the one that accepts numbers

游樂場鏈接

這就是為什么對於函數的並集 typescript 將推斷出參數的交集。 對於原始類型,這將始終減少到never ,但它對於 object 類型更有用,我們可以在其中創建滿足其他兩個 object 類型的交集的對象。

TS 盡其所能推斷參數的類型,但在這種情況下,推斷出的參數雖然正確,但並不是很有用。

在這種情況下,更好的解決方案是使用顯式通用簽名:

type Filter = {
  (arr: string[], f: (item: string) => boolean): string[]
  (arr: number[], f: (item: number) => boolean): number[]
}

let filter: Filter = <T extends string | number>(arr: T[], func: (item: T) => boolean): T[] => {
    let result: T[] = []
    for (let i in arr) {
        let item = arr[i]
        if (func(item)) {
            result.push(item)
        }
    }
    return result;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM