TypeScript特殊类型变量声明及JSON‘alive?’字段类型适配问题
嘿,针对你的两个TypeScript问题,我来给你详细拆解解答:
TypeScript提供了多种特殊类型来满足不同场景的需求,下面是几种常用的:
联合类型(Union Types):当变量可以是多种类型中的一种时使用,用
|分隔类型。比如你需要一个变量既可以是状态字符串也可以是错误码:let requestStatus: "success" | "error" | number; requestStatus = "success"; // 合法 requestStatus = 404; // 合法 requestStatus = "pending"; // 报错,不在允许的类型范围内交叉类型(Intersection Types):把多个类型的属性合并成一个新类型,适合需要同时拥有多个类型特征的对象,用
&连接:type BasicUser = { id: number; name: string }; type AdminPrivileges = { isAdmin: boolean; manageUsers: () => void }; type AdminUser = BasicUser & AdminPrivileges; const admin: AdminUser = { id: 1, name: "Alice", isAdmin: true, manageUsers: () => console.log("Managing users...") };字面量类型(Literal Types):严格限制变量只能是某个特定的字面量值,常和联合类型搭配来定义有限的可选值:
let direction: "left" | "right" | "up" | "down"; direction = "left"; // 合法 direction = "forward"; // 报错,不在可选值里unknown类型:比
any更安全的“任意类型”——它可以接收任何值,但在使用前必须先做类型判断,避免了any带来的类型不安全问题:let rawValue: unknown; rawValue = "hello world"; if (typeof rawValue === "string") { console.log(rawValue.toUpperCase()); // 合法,此时TS知道它是string类型 }元组类型(Tuples):固定长度和对应位置类型的数组,适合表示结构固定的集合,比如坐标、键值对:
let coordinate: [number, number]; coordinate = [10, 20]; // 合法 coordinate = [10, 20, 30]; // 报错,长度不匹配枚举类型(Enums):定义一组命名的常量,让代码更具可读性,避免直接使用魔法值:
enum OrderStatus { Pending, Shipped, Delivered, Cancelled } let myOrderStatus: OrderStatus = OrderStatus.Shipped;
当JSON字段包含?这类不符合JavaScript标识符规则的字符时,TypeScript的类型定义只需要用引号包裹字段名就能识别,不管是接口还是类型别名都适用:
方法1:用接口定义Person类型
interface Person { name: string; age: number; "alive?": boolean; // 用双引号包裹带特殊字符的字段名 } // 假设你加载的JSON数据如下 const personData = { name: "John", age: 30, "alive?": true }; const person: Person = personData; // 完全匹配,不会报错
方法2:用类型别名定义Person类型
type Person = { name: string; age: number; "alive?": boolean; };
访问字段的注意事项
访问这个带特殊字符的字段时,不能直接用点语法(比如person.alive?会被解析成可选链操作符),必须用括号加引号的方式:
console.log(person["alive?"]); // 正确访问方式
另外,如果你是通过import直接加载JSON文件,记得在tsconfig.json中开启resolveJsonModule选项(TypeScript 2.9及以上版本支持):
{ "compilerOptions": { "resolveJsonModule": true, "esModuleInterop": true } }
内容的提问来源于stack exchange,提问作者Juliano Carvalho

