TypeScript+React从MySQL取数:如何确保数据匹配接口类型?
解决方案
首先,你的代码存在异步逻辑错误:fetch返回的是Promise对象,不能直接展开赋值给setData,必须在then回调内处理解析后的数据。
接下来针对TypeScript类型校验的问题,提供两种可行方案:
方案1:类型断言(快速但无运行时校验)
如果你完全信任后端返回的数据严格符合QuizStructure接口,可以使用类型断言告诉TypeScript解析后的数据类型:
const [data, setData] = useState<QuizStructure[]>([]) function databaseFetch(){ fetch('/api/quizFetch') .then(res => res.json()) .then(parsedData => { // 使用类型断言告知TS数据符合接口 setData(parsedData as QuizStructure[]) }) .catch(err => console.log('error with data collection,', err)); }
注意:这种方式仅在编译阶段生效,如果后端返回数据不符合接口(比如age是字符串),运行时会出现隐藏问题。
方案2:运行时类型守卫(安全且符合TypeScript设计初衷)
为了兼顾编译时类型检查和运行时数据合法性,推荐编写类型守卫函数,主动校验数据结构:
interface QuizStructure { name: string, age: number, favoriteHobby: string } // 类型守卫函数:检查单个对象是否符合QuizStructure function isQuizStructure(item: unknown): item is QuizStructure { if (typeof item !== 'object' || item === null) return false; const candidate = item as QuizStructure; return ( typeof candidate.name === 'string' && typeof candidate.age === 'number' && typeof candidate.favoriteHobby === 'string' ); } // 检查数组是否全为QuizStructure类型 function isQuizStructureArray(items: unknown): items is QuizStructure[] { if (!Array.isArray(items)) return false; return items.every(isQuizStructure); } // 组件内代码 const [data, setData] = useState<QuizStructure[]>([]) function databaseFetch(){ fetch('/api/quizFetch') .then(res => res.json()) .then(parsedData => { if (isQuizStructureArray(parsedData)) { setData(parsedData); } else { console.error('返回数据不符合预期格式', parsedData); // 可以在这里添加错误处理逻辑,比如设置默认数据 } }) .catch(err => console.log('error with data collection,', err)); }
这种方式既让TypeScript确认数据类型,又能在运行时拦截不符合格式的数据,避免后续渲染出错。
内容的提问来源于stack exchange,提问作者user19568466
相关产品推荐
相关产品推荐

