TypeScript中如何为fetch返回的JSON响应指定IList接口类型?
问题原因
你之前的类型标注未生效核心有两个问题:
- 复用了
response变量:初始response是Fetch API返回的原生Response类型,后续你把解析后的JSON数据赋值给同一个变量,造成类型冲突,类型断言无法正常生效。 as类型断言仅在编译期生效,不会做任何运行时结构校验,如果你没有给函数定义返回值类型,TS也无法自动将返回值关联到IList[]类型。
解决方案
方案1:仅编译期类型标注(适合接口返回结构稳定可信任的场景)
直接拆分变量,给解析后的数据明确指定类型即可,示例代码如下:
interface IList { id: string; qty: number; } async function fetchPlaces(): Promise<IList[]> { // 存储原生Response对象,不要复用这个变量存解析后的数据 const response = await fetch(`./data/list.json`); // 单独声明解析后的数据变量,通过as断言指定类型 const listData = await response.json() as IList[]; return listData; }
调用该函数时,返回值会被TS自动识别为IList[]类型,可正常获取类型提示和校验。
方案2:增加运行时结构校验(适合需要严格保证数据结构的场景)
如果需要避免服务端返回异常结构导致前端业务报错,可以增加类型守卫做运行时校验,TS会自动推导出正确的类型,不需要额外断言:
interface IList { id: string; qty: number; } // 类型守卫:校验单个对象是否符合IList结构 function isIList(data: unknown): data is IList { return typeof data === 'object' && data !== null && 'id' in data && typeof (data as IList).id === 'string' && 'qty' in data && typeof (data as IList).qty === 'number'; } async function fetchPlaces(): Promise<IList[]> { const response = await fetch(`./data/list.json`); const rawData = await response.json(); // 校验外层是否为数组 if (!Array.isArray(rawData)) { throw new Error('返回数据格式错误,应为数组类型'); } // 校验每一项的结构是否符合IList要求 if (!rawData.every(item => isIList(item))) { throw new Error('返回数据元素不符合IList结构要求'); } return rawData; }
内容的提问来源于stack exchange,提问作者Alicia Y
相关产品推荐
相关产品推荐

