簡體   English   中英

TypeScript類型推斷

[英]TypeScript type inference

在下面的代碼中,我嘗試創建一個類型安全的函數來訪問給定輸入的data屬性。 我的目標是避免在任何地方重復訪問data ,並且為此值得,我希望將樣板保持在最低限度(例如,我希望TypeScript推斷出盡可能多的類型)。

interface User {
    name: string
}

interface HttpResponse<T> {
    data: T
    status: number
}

type HttpPromise<T> = Promise<HttpResponse<T>>

function fetch<T>(url: string): HttpPromise<T> {
    return
}

function getData<T>(response: HttpResponse<T>): T {
    return response.data
}

// Doesn't work: 'Promise<{}>' is not assignable to type 'Promise<User>'.
function fetchUser(): Promise<User> {
    return fetch('https://...').then(getData)
}

我知道如何通過明確說明更多類型來使其工作,但我不知道為什么這不起作用。 尤其是:

  1. {}類型來自哪里(在Promise<{}> )?
  2. 為什么TypeScript不能根據返回類型正確推斷表達式的類型?

使用代碼鏈接到TypeScript的游樂場。

讓我們從解決方案開始:

function fetchUser(): Promise<User> {
    return fetch<User>('https://...').then(getData)
}

為了使類型推斷起作用,我們需要為TypeScript提供一個起始點,在這種情況下,它是我們用來啟動執行的函數。 如果我們讓fetch方法泛型T參數具有默認值(即{}),那么TypeScript將使用該類型來確定所有連接的函數調用,基本上使thengetData繼承該默認類型。 最后,當TypeScript到達必須驗證最后一個函數簽名( getData )和外部fetchUser簽名之間的類型正確性時,它將發現沖突,因為假定getData與{}類型一起工作,並且fetchUser明確指出它是有效的用戶類型。

當您完全省略fetchUser函數返回的類型時,可以比較TypeScript將如何計算返回的類型:

function fetchUser() {
    return fetch<User>('https://...').then(getData)
}

如果將鼠標懸停在fetchUser函數上,您將看到TypeScript從內部提取函數簽名和其仍然是Promise <User>推斷出User類型。

對於您的第一個問題,TypeScript抱怨類型為Promise<{}>是,如果您沒有為返回promise的泛型函數指定類型,則默認情況下為Promise<{}>

考慮到這一點,通過調用fetch('http://...')而不提供type參數,TypeScript將推斷它是Promise<HttpResponse<{}>>

我假設您可以通過在fetchUser調用fetch時指定User類型來使其工作,如下所示:

return fetch<User>('https://...').then(getData);

如果您直接將調用返回到fetch ,那么您正在尋找的推理將會起作用。 就像是:

async function getValueAsync<T>(): Promise<T> {
    return null;
}

function testGetValueAsync(): Promise<User> {
    return getValueAsync();
}

但是,由於您正在鏈接該調用,因此fetch調用中沒有任何內容告訴TypeScript它返回的是什么類型。

因此,您需要進行的最小更改是在調用fetch時指定User類型

return fetch<User>('https://...').then(getData);

暫無
暫無

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

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