// 定义条件类型IsString<T>,用于判断类型T是否为string类型
type IsString<T> = T extends string? true : false;
function processValue<T>(value: T): T extends string? string : T {
// 使用类型守卫判断value是否为string类型
if (typeof value ==='string') {
// 如果是string类型,使用类型断言将其转换为string类型并转换为大写
return value.toUpperCase() as T extends string? string : T;
} else {
// 如果不是string类型,保持不变
return value;
}
}
实现思路及TypeScript类型系统的作用
- 定义条件类型
IsString<T>
:
- 使用条件类型语法
T extends string? true : false
。如果类型 T
可以赋值给 string
类型(即 T
是 string
类型或其子类型),则返回 true
,否则返回 false
。这一步利用了TypeScript类型系统的条件类型功能,它允许我们根据类型关系进行类型的选择。
- 实现
processValue
函数:
- 函数定义:
function processValue<T>(value: T): T extends string? string : T
表示函数接收一个泛型参数 value
,返回值类型根据 T
是否为 string
类型而不同。如果 T
是 string
类型,返回 string
类型;否则返回 T
类型。这里利用了TypeScript类型系统的泛型和条件类型功能,使得函数能够根据传入参数的实际类型返回不同类型的值。
- 类型守卫:
if (typeof value ==='string')
使用JavaScript的 typeof
操作符作为类型守卫。在TypeScript中,当进入这个 if
分支时,TypeScript类型系统能够基于这个运行时检查,智能地缩小 value
的类型范围为 string
。这体现了TypeScript类型系统与JavaScript运行时检查的结合,在运行时检查的基础上,为类型推断提供更多信息。
- 类型断言与转换:在
if
分支内,value.toUpperCase()
将 string
类型的值转换为大写。然后使用类型断言 as T extends string? string : T
,这是因为TypeScript可能无法完全根据之前的类型守卫推断出返回值的准确类型,通过类型断言明确告诉TypeScript返回值的类型,确保类型安全。在 else
分支,直接返回 value
,因为 value
不是 string
类型,保持其原始类型。整个过程充分利用了TypeScript类型系统的类型推断、类型守卫和类型断言等功能,确保函数在不同类型输入下的类型安全和正确行为。