在React中使用useState时,如何让TypeScript检测any类型?
问题本质
当前代码中,res.json()默认返回any类型,而TypeScript允许any赋值给任意类型,因此即便fetch返回的数据结构和TTOrigin[]不匹配,也不会触发编译错误。要让TypeScript对此类场景进行类型检测,可以通过以下几种方式实现:
方法1:为res.json()指定泛型类型
直接在res.json()中传入期望的类型,让TypeScript将返回值视为该类型,若后续赋值不符合类型定义会直接报错:
import { useEffect, useState } from 'react' export type TTOrigin = { name: 'Name1' | 'Name2' url: string } export function App() { const [data, setData] = useState<TTOrigin[]>([]) useEffect(() => { fetch('https://swapi.dev/api/people/1/') .then((res) => res.json<TTOrigin[]>()) // 显式指定泛型类型 .then((json) => setData(json)) // 若json结构不符合TTOrigin[],TypeScript会抛出编译错误 .catch((err) => console.log(err)) }, []) return <h1>App</h1> }
注意:这种方式属于类型断言,仅在编译阶段做类型检查,不会在运行时验证数据结构是否真实符合预期。
方法2:使用类型守卫实现编译+运行时双重检查
编写类型守卫函数,验证返回的JSON数据是否符合TTOrigin[]的结构,既在运行时拦截非法数据,也让TypeScript正确推断类型:
import { useEffect, useState } from 'react' export type TTOrigin = { name: 'Name1' | 'Name2' url: string } // 类型守卫函数:验证值是否为TTOrigin数组 function isTTOriginArray(value: unknown): value is TTOrigin[] { if (!Array.isArray(value)) return false return value.every(item => typeof item === 'object' && item !== null && typeof item.name === 'string' && ['Name1', 'Name2'].includes(item.name) && typeof item.url === 'string' ) } export function App() { const [data, setData] = useState<TTOrigin[]>([]) useEffect(() => { fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then((json: unknown) => { if (isTTOriginArray(json)) { setData(json) // 此处TypeScript会识别json为TTOrigin[]类型 } else { console.error('返回数据不符合预期类型') } }) .catch((err) => console.log(err)) }, []) return <h1>App</h1> }
这种方式更严谨,能在运行时捕获不符合结构的数据,同时确保编译阶段的类型安全。
方法3:开启TypeScript严格模式
在tsconfig.json中开启严格模式相关配置,强制TypeScript对隐式any进行检测,从根源上避免无意识的any赋值:
{ "compilerOptions": { "strict": true, // 开启所有严格检查规则,包含noImplicitAny、strictNullChecks等 // 也可单独开启关键规则: // "noImplicitAny": true, // "strictNullChecks": true } }
开启noImplicitAny后,res.json()若不指定类型会直接报错,迫使你显式声明返回值类型(如转为unknown或具体业务类型),彻底杜绝any类型的隐式使用。
内容的提问来源于stack exchange,提问作者italant
相关产品推荐
相关产品推荐

