为何TypeScript在Promise场景下不执行类型校验?
为何TypeScript在Promise场景下未触发类型校验?
我得到了正确的运行结果,但这原本应该触发错误。我将数值类型的值赋值给了字符串类型的变量,却没有收到TypeScript的错误提示,这是为什么?
代码示例
const BEApi = new Promise((resolve) => { resolve({ string: 123 }); }); type MyDataType = { string: string; }; let myData: MyDataType | null = null; const myResponce = async () => { myData = (await BEApi) as MyDataType; console.log(myData); }; myResponce();
原因分析
核心问题出在**as MyDataType类型断言**上:
- TypeScript自动推断
BEApi的类型为Promise<{ string: number; }>,这一步的类型推断是准确的。 - 但你使用
as MyDataType时,相当于强制告诉TypeScript“忽略自动推断的类型,认定这个值就是MyDataType类型”。TypeScript会信任开发者的断言,跳过此处的类型兼容性校验,因此不会抛出错误。 - 另外,TypeScript是编译时类型检查工具,运行时不会做类型验证,所以代码能正常执行,但类型不匹配的隐患被掩盖了。
如果去掉类型断言,直接写myData = await BEApi,TypeScript会立刻报错,提示{string: number}类型无法赋值给MyDataType类型,这才是正常的类型校验行为。
正确的处理方式
1. 提前给Promise指定明确类型
在定义Promise时就指定返回类型,从源头避免类型推断错误:
type MyDataType = { string: string; }; // 明确指定Promise的返回类型为MyDataType const BEApi = new Promise<MyDataType>((resolve) => { // 此时如果传入数值123,TypeScript会直接在编译时报错 resolve({ string: "123" }); }); let myData: MyDataType | null = null; const myResponce = async () => { // 无需类型断言,直接赋值即可通过校验 myData = await BEApi; console.log(myData); }; myResponce();
2. 用类型守卫做运行时校验
如果无法保证后端返回数据的类型,建议添加类型守卫进行运行时检查,兼顾编译时校验和运行时安全:
type MyDataType = { string: string; }; const BEApi = new Promise((resolve) => { resolve({ string: 123 }); }); let myData: MyDataType | null = null; // 定义类型守卫函数 function isMyDataType(data: unknown): data is MyDataType { return ( typeof data === "object" && data !== null && "string" in data && typeof (data as MyDataType).string === "string" ); } const myResponce = async () => { const result = await BEApi; if (isMyDataType(result)) { myData = result; } else { console.error("后端返回数据类型不匹配"); } console.log(myData); }; myResponce();
内容的提问来源于stack exchange,提问作者Екатерина
相关产品推荐
相关产品推荐

