TypeScript报TS2339:类型'DATABASE_USERS'上不存在属性'username'求助
error TS2339: Property 'username' does not exist on type 'DATABASE_USERS'.
报错的根本原因是类型定义层级错误:
你定义的DATABASE_USERS接口本身已经是数字索引的用户集合类型,对应单个用户数组,但你在DATABASE接口中将users字段声明为DATABASE_USERS[],相当于把users定义成了二维用户数组,和pm.json里的一维用户数组结构不匹配。当你访问database.users[i]时,TS会认为拿到的是DATABASE_USERS类型(也就是一整组用户),自然找不到username属性。
方案1:调整接口定义,抽离单个用户类型(更推荐,可读性更高)
把单个用户的结构抽成独立接口,避免索引签名带来的混淆:
import * as fs from "fs"; // 单个用户的类型定义 interface DatabaseUser { username: string; key?: string; services?: any[]; // 兼容pm.json里的services字段 } interface DATABASE { users?: DatabaseUser[]; // 直接声明为用户对象数组即可 } const loadFile = (filename: string): string | null => { let retValue: string | null; try { retValue = fs.readFileSync(filename, { encoding: "utf-8" }) } catch(e) { retValue = null; } return retValue; }; const getUsersFromDB = (jsonPath: string): null | DATABASE => { const data: string | null = loadFile(jsonPath); let jsonData: DATABASE = {} as any; if (data) { try { jsonData = JSON.parse(data); } catch(error) { return null } } else { return null; } if (!data) { return null; } return jsonData; } const database = getUsersFromDB("./pm.json"); if (database?.users?.length) { console.log("USERS:"); for (let i = 0; i < database.users.length; ++i) { console.log(` ${i + 1} - ${database.users[i]?.username}`); } }
方案2:基于原有定义调整,去掉多余的数组嵌套
如果你要保留原来的DATABASE_USERS索引签名写法,只需要修改DATABASE接口的users字段类型即可:
interface DATABASE_USERS { [index: number]: { username: string, key?: string, services?: any[] } } interface DATABASE { users?: DATABASE_USERS // 去掉后面的[],不要嵌套数组 }
不需要校验services字段也可以不声明,TS不会对未声明的可选字段做强制校验,只要核心的username和可选的key存在即可正常访问。
内容的提问来源于stack exchange,提问作者String Manolo
相关产品推荐
相关产品推荐

