首页 > 其他分享 >TypeScript 类型断言、类型推论

TypeScript 类型断言、类型推论

时间:2024-08-04 14:53:57浏览次数:11  
标签:推论 TypeScript number 编译器 let 推断 类型

类型断言

类型断言是一种 TypeScript 特性,用于告诉编译器将一个值视为特定的类型,即使编译器本身的类型推断可能不同。

类型断言并不会改变变量的实际运行时类型,而是在编译阶段告知TypeScript编译器开发者期望该表达式具有某种类型。

注意:类型断言 不是 类型转换,因为转换通常意味着某种运行时的支持。但类型断言纯粹是一个编译时语法,只是在编译阶段起作用,不进行特殊的数据检查和解构,它没有运行时的影响。同时,它也是一种为编译器提供关于如何分析代码的方法

语法格式:

  1. <类型>值
  2. 值 as 类型

类型断言主要用于以下情况:

  1. 当 TypeScript 的类型推断不够精确,而开发者明确知道变量的实际类型时。
  2. 当需要访问特定类型的属性或方法,但 TypeScript 由于自身的类型限制不允许直接访问时。
let someValue: any = "Hello, TypeScript!";

// 方式一:<类型>值
let length1: number = (<string>someValue).length;

// 方式二:值 as 类型
let length2: number = (someValue as string).length;

当你在TypeScript里使用JSX时,只有 as 语法断言是被允许的。

类型推断

在 TypeScript 中,类型推论允许 TypeScript 在某些情况下根据变量的初始化值自动推断出变量的类型。

类型推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时。

  1. 变量初始化时的类型推论
    当声明一个变量并同时为其赋值时,TypeScript 会根据赋值的值来推断变量的类型。

示例:

let num = 5;  // TypeScript 会推断 num 的类型为 number
let isTrue = true;  // TypeScript 会推断 isTrue 的类型为 boolean
let arr = [1, 2, 3];  // TypeScript 会推断 arr 的类型为 number[]

let str = "Hello";  // TypeScript 会推断 str 的类型为 string
str = "hi"; // 合法,str 的类型为 string
str = 10;  // Error: 不能将类型“number”分配给类型“string”。

当需要从几个表达式中推断类型时候,会使用这些表达式的类型来推断出一个最合适的通用类型。

let arr = [0, 1, null];

数组 arr 中的元素包含了数字 01 ,以及 null ,所以数组元素的类型被推断为 numbernull 的联合类型,整个数组的类型就是 (number | null)[]

  1. 函数返回值的类型推论
    如果函数的返回值是通过计算得出的,并且没有显式指定返回值类型,TypeScript 会根据返回的表达式来推断函数的返回值类型。

示例:

function sum(a: number, b: number) {
  return a + b;  // TypeScript 会推断该函数的返回值类型为 number
}
  1. 对象属性的类型推论
    在对象初始化时,TypeScript 也会对对象属性进行类型推论。

示例:

// TypeScript 会推断 person 的类型为具有 name: string 和 age: number 属性的对象类型
let person = {
  name: "John",
  age: 30
}; 

// 对象字面量只能指定已知属性,并且“firstName”不在类型“{ name: string; age: number; }”中。
person = {
  firstName: "John",
  lastName: "Bob"
}

在这里插入图片描述

由于最终的通用类型取自候选类型,有些时候 候选类型 共享 相同的通用类型,但是却没有一个类型能做为所有候选类型的类型。
没有通用类型:

let zoo = [new Rhino(), new Elephant(), new Snake()];

在这种情况下,TypeScript 编译器 会根据数组中元素的实际类型来推断数组的类型。
在数组中, RhinoElephantSnake 是自定义的类,它们之间没有找到最佳通用类型,类型推断的结果为联合数组类型:(Rhino | Elephant | Snake)[]

如果想要TypeScript编译器 推断zoo的类型为Animal[],但是这个数组里没有对象是Animal类型的,因此不能推断出这个结果。
当候选类型不能作为最佳通用类型使用的时候,需要明确的指出类型:

let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];

既然TypeScript 编译器会自动判断变量的类型,那为什么还要在编写代码时明确类型声明呢?

JavaScript的变量没有类型,在运行时明确变量的值的类型。
在单纯的为变量a赋值时,a是什么类型都影响不大:a = 10a = "hello"a = true
假如a作为某个函数的参数,需要传递到函数中使用呢?

function sum(a, b) {
  return a + b;
}
console.log( sum(10, 15) );  // 25
console.log( sum("10", 15) );  // "1015"

假如要将计算结果进行展示或在别的函数里继续使用,会导致更多错误。
sum(10, 15)sum("10", 15)的计算结果相差很大,但是代码不会报错,那排查问题就会特别困难。
因此,明确声明该参数的类型可以防止意外传递错误类型的值,并且在阅读函数定义时就能清楚了解输入的预期。

function sum(a:number, b:number) {
  return a + b;
}
console.log( sum(10, 15) );  // 25
console.log( sum("10", 15) );  // Error: 类型“string”的参数不能赋给类型“number”的参数。

明确指出变量类型有以下好处:

  1. 增强代码的自解释性
    • 明确的类型声明使其他开发者在阅读代码时能更快速、清晰地理解变量的预期用途和可能的值。
  2. 提高代码的可维护性
    • 当代码规模较大或经过多人协作开发时,显式的类型有助于确保代码的一致性和规范性。
    • 未来进行代码修改和扩展时,清晰的类型信息可以降低出错的风险。
  3. 提前发现错误,增强类型安全性
    • 显式声明类型,编译器能在编译阶段检测到更多潜在的类型不匹配错误,减少潜在的运行时错误。
  4. 更好的开发工具支持
    • 开发工具可以基于明确的类型提供更准确和有用的代码提示、自动完成和重构功能。
  5. 文档化代码
    • 类型声明相当于为代码添加了一种内置的文档,方便后续开发者理解。

类型断言、类型推论的区别

类型断言

  • 手动干预:是开发者手动告诉编译器将某个值视为特定的类型,即使编译器本身的推断可能不同。
  • 显式语法:通过特定的语法 <类型>值值 as 类型 来实现。
  • 可能存在风险:如果断言不正确,可能在运行时导致错误,因为编译器在编译阶段不会深入检查断言的正确性。

类型推论(Type Inference):

  • 自动进行:TypeScript 编译器根据变量的初始化值或函数的返回值等上下文信息,自动推断出变量或返回值的类型。
  • 无需显式操作:开发者不需要进行任何特殊的语法或操作来触发类型推论,它是在编译时由编译器自动完成的。
  • 基于值:类型的推断是基于所赋的值或计算得出的结果。

标签:推论,TypeScript,number,编译器,let,推断,类型
From: https://blog.csdn.net/fishmemory7sec/article/details/140894724

相关文章

  • C自定义类型(结构体,联合体,枚举)详解
            在C语言中,数据类型可以分为内置类型(charshortintlongfloatdouble...)和自定义类型。内置类型是由编程语言本身定义的基本数据类型,而自定义类型是由程序员根据需要创建的数据类型。    自定义类型:  结构体,联合体(共用体),枚举。结构体:用于组......
  • 【Java】包装类型变量的形参传递,方法内修改后,方法外还是原值?
    背景前几天有个朋友写代码时,想把int变量作为形参传入方法中进行修改后,在方法外能够获取到修改后的变量进行下一步操作。类似这样:classTest{publicstaticvoidmain(String[]args){intx=1;add(x);System.out.println(x);}pub......
  • C++ 返回值类型推导
    C++返回值类型推导前言C++中获取函数签名可以很简单地用decltype(函数名)来获得,但是这样无法直接提取出返回值类型。有时我们需要获取函数或可调用对象的返回值类型,以便进行后续的操作,在泛型编程中很常用,特别是当不同的参数集的结果类型不同时。头文件<type_traits>:C......
  • C++ //练习 16.14 编写Screen类模板,用非类型参数定义Screen的高和宽。
    C++Primer(第5版)练习16.14练习16.14编写Screen类模板,用非类型参数定义Screen的高和宽。环境:LinuxUbuntu(云服务器)工具:vim 代码块template<intH,intW>classScreen{public:usingpos=string::size_type;Screen()=default;Screen(cha......
  • textx 模型的类型检查
    我正在尝试使用python的textx模块来解释语法的语言原型。我正在创建一个像这样的模型:fromtextximportmetamodel_from_strfunl_grammar="""Model:statement*=Statement;Statement:FunctionDefinition|Function;FunctionDefinition:name=ID......
  • Java中的不同数据类型的方法调用
    数组在Java中,数组是一个基础的数据结构,用来存储固定大小的同类型元素。数组本身在Java中是一个对象,但它的方法比较有限,主要依赖于Java的Arrays类来进行数组操作。排序sort():对整个数组或指定范围的元素进行排序。重载版本支持所有基本类型数组和对象数组。对于对象数组......
  • 【Java基础】02变量和数据类型
    变量一个数据存储空间的表示不同数据存入具有不同内存地址的空间,相互独立,内存地址不好记,通过变量名可以简单快速地找到数据。变量命名规则包含数字、字母、下划线、$不能以数字开头,不能是纯数字英文命名,要有意义帕斯克命名法(驼峰命名法)大骆驼:HelloWorld首字母大写,一般......
  • 【Python】数据类型之字符串
    本篇文章将继续讲解字符串其他功能:1、求字符串长度功能:len(str)  ,该功能是求字符串str的长度。代码演示:2、通过索引获取字符串的字符。功能:str[a]  str为字符串,a为整型。该功能是获取字符串str索引为a处的字符。注意:字符串的索引是从0开始的。代码演示:注意......
  • Java数据类型
    目录数据类型基本数据类型引用类型数据类型的转换数据类型基本数据类型Java语言提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型1.byte:byte数据类型是8位、有符号的,以二进制补码表示的整数;最小值是-128zhi(-2^7);最大值是127(2^7-1);默认......
  • 类型转换
    1.类型转换优先级如图所示2.转换方法强制转换自动转换3.转换问题1.内存溢出:在大容量转换为小容量时,如果容量过大而超过了小容量的类所能承受的范围,则会出错。如:2.精确问题:在小数转整数时,会出现误差如:3.相乘问题:未转换,已相乘。如:解决方法:......