TypeScript 02:interface、type 与类型收窄
TypeScript 02interface、type 与类型收窄1. interface给对象形状起名字第 1 课的{ name: string; age: number }每次都要重抄一遍——起个名字就能复用interfaceUser{name:stringage:number}functiongreet(u:User){return你好${u.name}}greet({name:Tom,age:18})// ✅greet({name:Tom})// ❌ Property age is missing in type User形状可以继承interfaceVipextendsUser{level:number}constv:Vip{name:Tom,age:18,level:3}2. type另一种起名方式type也能给形状起名还擅长做interface做不到的事——给联合、字面量起名typeIDstring|numbertypeStatusloading|success|errorletpage:Statusloadingpageloaded// ❌ Type loaded is not assignable to type Status拼错立刻暴露怎么选对象形状两者都能用团队统一一种即可联合类型、字面量类型只能用type。3. 可选属性?:与只读readonlyinterfaceProfile{name:stringemail?:string// 可有可无实际类型是 string | undefinedreadonlyid:number// 只能读不能改}constp:Profile{name:Tom,id:1}// 不写 email 合法p.id2// ❌ Cannot assign to id because it is a read-only property可选属性的实际类型是string | undefined用之前要确认存在if(p.email){sendTo(p.email)// 这里 TS 知道 email 一定是 string}4. 字面量类型与 as conststring是「任意字符串」loading本身也是一个类型——值被锁死为这一个constROUTES{home:/,about:/about,}asconst// 每个字段锁成字面量类型 / 和 /about且全部只读ROUTES.home/x// ❌ Cannot assign to home because it is a read-only property5. 类型收窄使用联合类型的前提联合类型的值不能直接用某一方的特有能力——必须先收窄functiondescribe(id:string|number){// ❌ id.toUpperCase()Property toUpperCase does not exist on type string | numberif(typeofidstring){returnid.toUpperCase()// ✅ 这里 TS 知道是 string}returnid.toFixed(2)// ✅ 这里 TS 知道是 number}三种常用收窄手段if(typeofxstring){}// ① typeof区分原始类型if(flyinanimal){}// ② in对象有没有这个字段if(r.oktrue){}// ③ 具体值比较配合字面量类型③ 的经典形态是可辨识联合——后端接口最常见typeApiResult{ok:true;data:string[]}|{ok:false;message:string}functionhandle(r:ApiResult){if(r.ok){returnr.data.length// 收窄到成功分支才有 data}returnr.message// 收窄到失败分支才有 message}6. unknown安全的 anyany是「随便用」unknown是「类型未知但用之前必须收窄」constinput:unknownJSON.parse(text)input.toFixed(2)// ❌ input is of type unknownif(typeofinputnumber){input.toFixed(2)// ✅ 收窄后才能用}外部数据接口返回、JSON优先按unknown处理逼自己先判断再用。7. 高频报错速查报错人话Property x does not exist on type string | number联合类型没收窄就想用单方方法input is of type unknownunknown 必须先收窄再使用Cannot assign to id because it is a read-only property给 readonly 赋值了Type loaded is not assignable to type Status字面量不在允许列表多半拼错