8. TypeScript 类型推论和类型断言

类型推论

在TypeScript 中,有很多时间并不需要显式地指定变量的类型,TypeScript的一大优势是它的类型推论机制,可以自动推断变量、函数参数和返回值的类型,从而减少了手动类型注解的需求。

变量类型推论

TypeScript 可以根据变量的初始值推断出变量的类型。例如:

typescript 复制代码
let x = 3; // x 被推断为 number 类型
let y = "hello"; // y 被推断为 string 类型

如果没有初始值,TypeScript 会将变量推断为 any 类型。

typescript 复制代码
let z; // z 被推断为 any 类型

函数参数类型推论

TypeScript 可以根据函数参数的默认值推断出参数的类型。例如:

typescript 复制代码
function greet(name = "world") {
  console.log(`Hello, ${name}!`);
}

在上面的例子中,TypeScript 会推断 name 参数的类型为 string。

函数返回值类型推论

TypeScript 可以根据函数体中的代码推断出函数的返回值类型。例如:

typescript 复制代码
function add(a: number, b: number) {
  return a + b;
}

在上面的例子中,TypeScript 会推断 add 函数的返回值类型为 number。

类型断言

在 TypeScript 中,类型断言(Type Assertion)是一种告诉编译器变量的具体类型的方式。它允许你覆盖 TypeScript 的类型推断,如果你能明确变量的类型,就可以手动指定一个值的类型。

1. TypeScript 类型断言有两种语法形式:

typescript 复制代码
// 尖括号语法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

// as 语法
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

两种形式是等价的,但在 JSX 中只能使用 as 语法。

2. 常见用例

2.1 将一个联合类型断言为其中一个类型

当 TypeScript 不确定一个联合类型的变量到底是哪个类型时,我们只能访问此联合类型的所有类型中共有的属性或方法。如果需要访问特定类型的属性或方法,就需要使用类型断言。

typescript 复制代码
function getLength(something: string | number): number {
    if ((<string>something).length) {
        return (<string>something).length;
    } else {
        return something.toString().length;
    }
}

2.2 将一个父类断言为更加具体的子类

当我们需要访问子类特有的属性或方法时,可以使用类型断言将父类断言为子类。

typescript 复制代码
class ApiError extends Error {
    code: number = 0;
}
class HttpError extends Error {
    statusCode: number = 200;
}

function isApiError(error: Error) {
    if (typeof (error as ApiError).code === 'number') {
        return true;
    }
    return false;
}

2.3 将任意类型断言为 any

在某些情况下,我们可能需要临时绕过类型检查。可以使用 as any 将一个变量断言为 any 类型。

typescript 复制代码
let someValue: string = "this is a string";
let strLength: number = (someValue as any).length;

2.4 非空类型断言

非空类型断言 ! 是类型断言的一种形式,它用于确保一个值不是 null 或 undefined。格式为在变量前面加上!

typescript 复制代码
function printMessage(message?:string){
	console.log(message!.length); 
	/**
	因为message是可选参数,如果为undefined,编译会不通过,加上非空类型断言,
	**/
}

但是,滥用 any 类型可能导致类型检查失效,应谨慎使用。有时候不能直接进行类型断言,可能需要断言成any,再断言成其它类型。

3. 注意事项

3.1 类型断言不是类型转换

类型断言只是一种告诉编译器如何理解代码的方式,并不会真正影响变量的类型。

3.2 类型断言与类型声明的区别

类型断言和类型声明都可以指定变量的类型,但类型声明更加严格,会在编译阶段进行类型检查。而类型断言只在编译阶段起作用,不会影响运行时的类型。

typescript 复制代码
// 类型声明
let someValue: string = "this is a string";

// 类型断言
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

3.3 避免滥用类型断言

过度使用类型断言可能掩盖潜在的类型错误,降低代码的可维护性。应该尽量让 TypeScript 自动推断类型,只在必要时使用类型断言。

4. 总结

TypeScript 类型断言是一种强大的工具,允许我们手动指定变量的类型。合理使用类型断言可以提高代码的灵活性和可读性。但同时也要注意避免滥用,以免损失 TypeScript 静态类型检查的优势。

相关推荐
panxianren2 小时前
Bun 1.4 的 bun test --parallel 将 4 秒的测试套件缩短到约 1 秒
java·javascript
陈随易3 小时前
bm2,Node.js 与 Bun 项目部署新选择
前端·后端·程序员
可乐鸡翅yeah_5 小时前
FFmpeg 生成 HLS 独立分片 independent‑segments 参数到底有什么用
javascript·ffmpeg·音视频·safari·m3u8
福兮说5 小时前
canvas 旋转图片的六个坑:四角被裁、Math.ceil 多出 1px 黑边、JPG 角发黑、翻转方向反了
前端·javascript·图像处理·canvas
Ai-_Man6 小时前
您您这可以把Grok的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑
传人once6 小时前
多图片上传预览功能如何写
前端·css·html·jquery·html5
Eric.467 小时前
Wan‑Animate+MiniMax-H3 本地部署 AI 漫剧流水线:8G 显存动作迁移与动态分镜工程实战
前端·人工智能·comfyui·ai漫剧
liangshanbo12157 小时前
JavaScript 异步核心主线
javascript·事件循环·异步操作
传人once8 小时前
悬停旋转放大和位移效果如何写
javascript·css·动画
库拉镜像AI牛牛8 小时前
短剧内容自动化生产:知漫剧工作室落地教程
大数据·服务器·前端·人工智能·语音识别