Typescript 类型脚本类型推断

Typescript 类型脚本类型推断,typescript,type-inference,Typescript,Type Inference,在下面的代码中,我尝试创建一个类型安全函数,用于访问给定输入的data属性。我的目标是避免在任何地方重复访问数据,为此,我希望尽量减少样板文件(例如,我希望TypeScript推断尽可能多的类型) 用户界面{ 名称:string } 接口HttpResponse{ 数据:T 状态:编号 } 类型HttpPromise=Promise 函数获取(url:string):HttpPromise{ 返回 } 函数getData(响应:HttpResponse):T{ 返回响应.data } //不起作

在下面的代码中,我尝试创建一个类型安全函数,用于访问给定输入的
data
属性。我的目标是避免在任何地方重复访问
数据
,为此,我希望尽量减少样板文件(例如,我希望TypeScript推断尽可能多的类型)

用户界面{
名称:string
}
接口HttpResponse{
数据:T
状态:编号
}
类型HttpPromise=Promise
函数获取(url:string):HttpPromise{
返回
}
函数getData(响应:HttpResponse):T{
返回响应.data
}
//不起作用:“承诺”不可分配给类型“承诺”。
函数fetchUser():Promise{
返回获取('https://...)。然后(获取数据)
}
我知道如何通过显式地声明更多类型来使它工作,但我不知道为什么这已经不起作用了。特别是:

  • {}
    类型来自哪里(在
    Promise
    中)
  • 为什么TypeScript不能根据返回类型正确推断表达式的类型

  • 让我们从解决方案开始:

    function fetchUser(): Promise<User> {
        return fetch<User>('https://...').then(getData)
    }
    
    函数fetchUser():Promise{
    返回获取('https://...)。然后(获取数据)
    }
    
    为了使类型推断工作,我们需要给TypeScript一个起点,在本例中,这个起点就是我们启动执行的函数。如果我们让fetch方法generic T参数具有默认值(即{}),那么TypeScript将使用该类型来确定所有连接的函数调用,基本上使then和getData继承该默认类型。最后,当TypeScript必须验证最后一个函数签名(getData)和外部fetchUser签名之间的类型正确性时,它将发现冲突,因为假定getData与{}类型一起工作,而fetchUser明确声明它与用户类型一起工作

    当完全忽略fetchUser函数返回的类型时,您可以比较TypeScript如何计算返回的类型:

    function fetchUser() {
        return fetch<User>('https://...').then(getData)
    }
    
    函数fetchUser(){
    返回获取('https://...)。然后(获取数据)
    }
    

    如果您将鼠标悬停在fetchUser函数上,您将看到TypeScript从内部fetch函数签名及其仍然承诺推断出用户类型。对于第一个问题,TypeScript抱怨类型为
    承诺的原因是,如果没有为返回承诺的泛型函数指定类型,则默认情况下为
    promise

    记住这一点,通过调用
    fetch('http://...“)
    ,在不提供类型参数的情况下,TypeScript将推断它是
    Promise

    我假设您能够通过在
    fetchUser
    中调用
    fetch
    时指定
    User
    类型使其工作,如下所示:

    return fetch<User>('https://...').then(getData);
    
    return fetch<User>('https://...').then(getData);
    
    但是,由于您正在链接该调用,因此
    fetch
    调用中没有任何内容可以告诉TypeScript它返回的是什么类型

    因此,您需要做的最小更改是在调用
    fetch
    时指定
    User
    类型

    return-fetch('https://...)。然后(获取数据);
    
    async function getValueAsync<T>(): Promise<T> {
        return null;
    }
    
    function testGetValueAsync(): Promise<User> {
        return getValueAsync();
    }
    
    return fetch<User>('https://...').then(getData);