TypeScript调用promise.then()仍返回Promise类型报错排查
问题产生原因
你遇到的类型报错:
error: Type 'Promise<void | SunriseSunsetResultsType>' is not assignable to type 'string'.
核心原因有3个:
- Promise是异步操作的状态容器,所有
.then()/.catch()/.finally()调用的返回值永远是新的Promise实例,永远无法在同步代码流里直接拿到Promise内部包裹的异步结果。你把.then()返回的Promise直接赋值给msg,再传给innerText,本质是把Promise对象转成[object Promise]字符串,根本拿不到请求结果。 - 你的
.then()成功回调写了大括号包裹函数体,但没有写return关键字返回results字段,等价于回调返回undefined,所以TS才会推导出返回类型里带void。 fetch返回对象的.json()方法本身返回Promise,你在request函数里写(await fetch(url)).json()时漏了await,等于把JSON解析的Promise直接当成解析完成的结果返回,本身就存在逻辑错误。
修正方案
按以下规则调整代码即可:
- 所有依赖异步请求结果的逻辑(比如给DOM赋值),必须放到
.then()回调内部,或者用await拿到结果之后再执行,不能在Promise外部的同步上下文直接取值。 - 箭头函数用大括号包裹函数体时,必须显式写
return返回需要的值;如果只需要单表达式返回值,可以去掉大括号简化写法。 - 补全
.json()调用前的await,确保拿到解析完成的JSON对象。
修正后的完整代码:
import { HebCalResponseType, OpenweatherResponseType, SunriseSunsetResultsType, SunriseSunsetResponseType } from "../src/app"; const lat: number = 40.8915; const lng: number = -74.0119; const date: string = "2012-11-09"; const url: string = `https://api.sunrise-sunset.org/json?lat=${lat}&lng=${lng}&date=${date}&formatted=0`; async function request(url: string): Promise<HebCalResponseType | OpenweatherResponseType | SunriseSunsetResponseType> { // 补await,等待json解析完成 const jsonResult: HebCalResponseType | OpenweatherResponseType | SunriseSunsetResponseType = await (await fetch(url)).json(); return jsonResult; }; // 链式调用处理异步结果 request(url) .then(response => { // 显式return需要的字段 return (response as SunriseSunsetResponseType).results; }, error => { throw `failed to load ${url} with error ${error}`; }) .then(msg => { // 拿到结果之后再操作DOM const test: HTMLElement | null = document.getElementById("source"); if (test) { // 如果results是对象需要转字符串,直接赋值对象会显示[object Object] test.innerText = typeof msg === "string" ? msg : JSON.stringify(msg); } })
补充说明:如果SunriseSunsetResultsType是对象类型,直接赋值给innerText会显示[object Object],需要按业务需求取对应字符串字段、或者用JSON.stringify转成字符串再赋值。
内容的提问来源于stack exchange,提问作者pgolbus
相关产品推荐
相关产品推荐

