1、! 非空断言操作符

x! 将从 x 值域中排除 null 和 undefined(在某个变量后面加上!就代表着这个变量肯定有值)

2、?. 运算符

如果遇到 null 或 undefined 就可以立即停止某些表达式的运行

3、?? 空值合并运算符

// 当左侧操作数为 null 或 undefined 时,其返回右侧的操作数,否则返回左侧的操作数
// 与逻辑或 || 运算符不同,逻辑或会在左操作数为 false 值时返回右侧操作数
console.log(false || '哈哈哈')  // 哈哈哈
console.log(false ?? '哈哈哈')  // false
// 不能与 && 或 || 操作符共用!!!
// 如果??和&&或||共用了会抛出 SyntaxError
// 但当使用括号来显式表明优先级时是可行的
(null || undefined ) ?? "foo"; // 返回 "foo"

4、?: 可选属性

// age变成了可选属性,调用Person时可传可不传
type Person = {
	name: string
	age?: number
}
// 1.如果存在一个属性名且该属性名对应的值不是函数类型,使用?.仍然会产生一个 TypeError 异常。
// 2.可选链的运算行为被局限在属性的访问、调用以及元素的访问————它不会沿伸到后续的表达式中,也就是说可选调用不会阻止 a?.b / someMethod() 表达式中的除法运算或 someMethod 的方法调用。

5、& 运算符

// 在ts中交叉类型是将多个类型合并为一个类型
// 通过&运算符可以将现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性
type Animal = { age: number; };
type Dog= Animal & { name: string; };
let tony: Dog = {
  age: 2,
  name: '旺财'
}

6、| 分隔符

// 在TypeScript中联合类型(Union Types)表示取值可以为多种类型中的一种,联合类型使用 | 分隔每个类型
// 联合类型通常与 null 或 undefined 一起使用
// 类型保护
// 当使用联合类型时,我们必须尽量把当前值的类型收窄为当前值的实际类型,而类型保护就是实现类型收窄的一种手段
// 类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。
let name: string | number

7、_ 数字分隔符

// TypeScript 2.7 带来了对数字分隔符的支持,正如数值分隔符 ECMAScript 提案中所概述的那样
// 对于一个数字字面量,你现在可以通过把一个下划线作为它们之间的分隔符来分组数字
const inhabitantsOfMunich = 1_464_301;
const distanceEarthSunInKm = 149_600_000;
const fileSystemPermission = 0b111_111_000;
const bytes = 0b1111_10101011_11110000_00001101;
// 分隔符不会改变数值字面量的值,但逻辑分组使人们更容易一眼就能读懂数字
// 使用限制
// 虽然数字分隔符看起来很简单,但在使用时还是有一些限制。比如你只能在两个数字之间添加 _ 分隔符,也不能连续使用多个 _ 分隔符。
// 解析分隔符
// 解析数字的函数是不支持分隔符:
Number('123_456') // NaN
parseInt('123_456') // 123
parseFloat('123_456') // 123
// 可以借用正则表达式来解析
let str = '123_456'
console.log(str.replace(/[^0-9]/gu,'')) //123456

8、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

9、#XXX 私有字段

// 在 TypeScript 3.8 版本就开始支持 ECMAScript 私有字段
// 1.私有字段以 # 字符开头,有时我们称之为私有名称;
// 2.每个私有字段名称都唯一地限定于其包含的类;
// 3.不能在私有字段上使用 TypeScript 可访问性修饰符(如 public 或 private);
// 4.私有字段不能在包含的类之外访问,甚至不能被检测到。
class Person {
	#name: string
    constructor(name: string){
		this.#name = name
	}
	a(){
		console.log(this.#name)
	}
}
let person = new Person('名字');
// Property '#name' is not accessible outside class 'Person' because it has a private identifier 
// 翻译:属性'#name'在类'Person'之外不可访问,因为它有一个私有标识符
console.log(person.#name); 
console.log(person.a()); //名字