- TypeScript 基础
- TypeScript - 首页
- TypeScript - 路线图
- TypeScript - 概述
- TypeScript - 环境设置
- TypeScript - 基本语法
- TypeScript vs. JavaScript
- TypeScript - 特性
- TypeScript - 变量
- TypeScript - let & const
- TypeScript - 运算符
- TypeScript 基本类型
- TypeScript - 类型
- TypeScript - 类型注解
- TypeScript - 类型推断
- TypeScript - 数字
- TypeScript - 字符串
- TypeScript - 布尔值
- TypeScript - 数组
- TypeScript - 元组
- TypeScript - 枚举
- TypeScript - any
- TypeScript - never
- TypeScript - 联合类型
- TypeScript - 字面量类型
- TypeScript - Symbols
- TypeScript - null vs. undefined
- TypeScript - 类型别名
- TypeScript 控制流
- TypeScript - 决策
- TypeScript - if 语句
- TypeScript - if else 语句
- TypeScript - 嵌套 if 语句
- TypeScript - switch 语句
- TypeScript - 循环
- TypeScript - for 循环
- TypeScript - while 循环
- TypeScript - do while 循环
- TypeScript 函数
- TypeScript - 函数
- TypeScript - 函数类型
- TypeScript - 可选参数
- TypeScript - 默认参数
- TypeScript - 匿名函数
- TypeScript - Function 构造函数
- TypeScript - rest 参数
- TypeScript - 参数解构
- TypeScript - 箭头函数
- TypeScript 接口
- TypeScript - 接口
- TypeScript - 接口扩展
- TypeScript 类和对象
- TypeScript - 类
- TypeScript - 对象
- TypeScript - 访问修饰符
- TypeScript - 只读属性
- TypeScript - 继承
- TypeScript - 静态方法和属性
- TypeScript - 抽象类
- TypeScript - 存取器
- TypeScript - 鸭子类型
- TypeScript 高级类型
- TypeScript - 交叉类型
- TypeScript - 类型守卫
- TypeScript - 类型断言
- TypeScript 类型操作
- TypeScript - 从类型创建类型
- TypeScript - keyof 类型运算符
- TypeScript - typeof 类型运算符
- TypeScript - 索引访问类型
- TypeScript - 条件类型
- TypeScript - 映射类型
- TypeScript - 模板字面量类型
- TypeScript 泛型
- TypeScript - 泛型
- TypeScript - 泛型约束
- TypeScript - 泛型接口
- TypeScript - 泛型类
- TypeScript 其他
- TypeScript - 三斜杠指令
- TypeScript - 命名空间
- TypeScript - 模块
- TypeScript - 环境声明
- TypeScript - 装饰器
- TypeScript - 类型兼容性
- TypeScript - Date 对象
- TypeScript - 迭代器和生成器
- TypeScript - Mixins
- TypeScript - 实用程序类型
- TypeScript - 装箱和拆箱
- TypeScript - tsconfig.json
- 从 JavaScript 到 TypeScript
- TypeScript 有用资源
- TypeScript - 快速指南
- TypeScript - 有用资源
- TypeScript - 讨论
TypeScript - 泛型约束
在 TypeScript 中,泛型约束允许你指定对可与泛型类型参数一起使用的类型的限制。这通过确保泛型代码仅适用于兼容的数据类型来增加一层类型安全。
问题示例
在深入研究泛型约束之前,让我们了解需要应用泛型约束的问题示例。
示例
在下面的代码中,我们创建了merge()泛型函数,它将两个对象作为参数,使用扩展运算符合并它们,并返回合并后的对象。
之后,我们通过传递两个对象作为参数来调用merge()函数,它成功地打印了合并后的对象。
// Generic function to merge two objects function merge<T, U>(obj1: T, obj2: U) { return {...obj1, ...obj2}; } // Invoke the function const mergedObj = merge({name: 'Sam'}, {age: 30}); console.log(mergedObj); // Output: {name: 'Sam', age: 30}
编译后,它将生成以下 JavaScript 代码。
// Generic function to merge two objects function merge(obj1, obj2) { return Object.assign(Object.assign({}, obj1), obj2); } // Invoke the function const mergedObj = merge({ name: 'Sam' }, { age: 30 }); console.log(mergedObj); // Output: {name: 'Sam', age: 30}
输出
上面示例代码的输出如下:
{name: 'Sam', age: 30}
merge()函数具有泛型参数。因此,它可以接受任何数据类型的数值作为参数,包括对象。如果你传递布尔值作为第二个参数会怎样?让我们看看下面的例子。
示例
下面的示例代码与之前的代码非常相似。我们只是在调用时将merge()函数的第二个参数更改为布尔值。
// Generic function to merge two objects function merge<T, U>(obj1: T, obj2: U) { return {...obj1, ...obj2}; } // Invoke the function const mergedObj = merge({name: 'Sam'}, true); console.log(mergedObj); // Output: {name: 'Sam'}
编译后,它将生成以下 JavaScript 代码。
// Generic function to merge two objects function merge(obj1, obj2) { return Object.assign(Object.assign({}, obj1), obj2); } // Invoke the function const mergedObj = merge({ name: 'Sam' }, true); console.log(mergedObj); // Output: {name: 'Sam'}
输出
上面示例代码的输出如下:
{name: 'Sam'}
上面的代码只打印第一个对象,因为第二个参数是布尔值而不是对象。为了解决上面示例代码中发现的问题,开发人员可以使用泛型约束。
TypeScript 中泛型约束的工作原理?
泛型约束允许我们将泛型参数限制为仅接受特定类型的数值。即你可以缩小泛型参数的类型。
语法
您可以按照以下语法使用泛型参数的泛型约束。
function merge<T extends object>(obj1: T) { // Code to execute }
在上面的语法中,“T”是一个泛型类型,“extends”是一个关键字,“object”是一个数据类型。
在这里,“T”只接受具有“object”数据类型的数值。
让我们通过下面的例子来更多地了解泛型约束。现在,如果你尝试编译下面的代码,你将得到编译错误,因为泛型参数只能接受对象参数,但我们传递的是布尔值。
// Generic function to merge two objects function merge<T extends object, U extends object>(obj1: T, obj2: U) { return { ...obj1, ...obj2 }; } // Invoke the function const mergedObj = merge({ name: 'Sam' }, true); console.log(mergedObj);
编译上面的 TypeScript 代码时,编译器会显示以下错误:
Argument of type 'boolean' is not assignable to parameter of type 'object'.
这样,我们可以限制泛型参数以接受特定数据类型的数值。
示例(使用接口扩展泛型类型)
让我们逐步了解下面的代码。
我们定义了包含 name、age 和 email 属性的“Person”接口。
接下来,我们定义了包含“empCode”和“empDept”属性的“Employee”接口。
merge()函数包含两个泛型参数 T(Person 类型)和 U(Employee 类型)。
在merge()函数中,我们合并两个对象。
之后,我们分别定义了两个 Person 和 Employee 类型的对象。
接下来,我们通过传递对象作为参数来调用merge()函数,代码运行没有任何错误。
// Define Person interface interface Person { name: string; age: number; email: string; } // Define Employee interface interface Employee { empCode: number; empDept: string; } // Generic function which takes Objects of the Person and Employee interfaces types function merge<T extends Person, U extends Employee>(obj1: T, obj2: U) { return { ...obj1, ...obj2 }; } // Create two objects const person: Person = { name: 'John', age: 30, email: '[email protected]' }; const employee: Employee = { empCode: 1001, empDept: 'IT' }; // Invoke the function const mergedObj = merge(person, employee); console.log(mergedObj);
编译后,它将生成以下 JavaScript 代码。
// Generic function which takes Objects of the Person and Employee interfaces types function merge(obj1, obj2) { return Object.assign(Object.assign({}, obj1), obj2); } // Create two objects const person = { name: 'John', age: 30, email: '[email protected]' }; const employee = { empCode: 1001, empDept: 'IT' }; // Invoke the function const mergedObj = merge(person, employee); console.log(mergedObj);
输出
上面示例代码的输出如下:
{ name: 'John', age: 30, email: '[email protected]', empCode: 1001, empDept: 'IT' }
在泛型约束中使用类型参数
TypeScript 还允许你定义一个类型参数,该参数受同一函数的另一个参数约束。
让我们通过下面的例子来了解它。
示例
在下面的代码中,类型“U”扩展了在第一个参数中接收的对象的键。因此,它将接受obj对象的键作为参数,以避免函数体中的错误。
接下来,我们通过传递“obj”对象作为参数来调用getValue()函数。它在输出中打印键值。
// Parameter U ensures that the key is a valid key of the object T. function getValue<T extends object, U extends keyof T>(obj: T, key: U) { return obj[key]; } // Define an object const obj = { name: 'Sam', age: 34 }; // Get the value of the key 'name' const name1 = getValue(obj, 'name'); console.log(name1); // Sam
编译后,它将生成以下 JavaScript 代码。
// Parameter U ensures that the key is a valid key of the object T. function getValue(obj, key) { return obj[key]; } // Define an object const obj = { name: 'Sam', age: 34 }; // Get the value of the key 'name' const name1 = getValue(obj, 'name'); console.log(name1); // Sam
输出
上面示例代码的输出如下:
Sam
我们了解到泛型约束对于接受特定数据类型的数值作为参数而不是接受所有数据类型的数值很有用。