Skip to content

操作符 ​

https://juejin.cn/post/6944710676464009223

https://www.cnblogs.com/zhangguicheng/p/15733416.html

1. ?. ​

该操作符是可选操作符, 在Js 中也有该符号, 都是在遇到变量为null 和 undefined 的时候可以及时停止运算, 防止出现Uncaught TypeError: Cannot read properties of undefined 的报错.

具体形式为:

typescript
const person = {
  address: {
    street: {}
  }
}
const city = person.address.info?.city

计算结果如下所示:

image-20230309100728451

2. ! ​

非空断言运算符, 主要用于声明操作的对象是非null 和非undefined 类型

typescript
interface Person {
  name: string
  age: number
}
async () => {
  const person: Person | undefined = await getPersonInfo()
  return person!.age
}

3. ?? ​

该操作符在Js 中也存在, 其表示空值运算符, 即当左侧操作数为null或者undefined时,返回右侧的操作数,否则返回左侧的操作数.

和|| 操作符不一样的是, 逻辑或会在左侧操作数为falsy 时( 如: 空字符串, 0等)返回右侧操作数.

4. & ​

交叉类型运算符,用于将多种类型叠加到一起成为一个新类型

这里分多种情况

  • Interface中同名属性类型不同的交叉
typescript
interface X {
  c: string;
  d: string;
}

interface Y {
  c: number;
  e: string
}

type Z1 = X & Y
// {
//   c: never
//   d: string
//   e: string
// }
  • nterface中同名属性类型相同的交叉
typescript
interface X {
  c: string;
  d: string;
}

interface Y {
  c: string;
  e: string
}

type Z1 = X & Y
// {
//   c: string
//   d: string
//   e: string
// }
  • Type中同名属性类型不同的交叉
typescript
type Env1 = {
  name: string
  age: string
};
type Env2 = {
  name: number
  info: string
};
type EnvInter = Env1 & Env2;
// {
//   name: never
//   age: string
//   e: string
// }
  • Type中同名属性类型相同的交叉
typescript
type Env1 = 'prod' | 'test' | 'dev';
type Env2 = 'prod' | 'boe' | 'ppe';
type EnvInter = Env1 & Env2;  // 'prod'

简单来讲, 就是如果接口联合起来, 新的类型继承两者所有的属性, 如果同名属性的类型有冲突, 该属性的类型是never . 对于type 形式的联合类型就会特殊一点, 如上所示取并集.

扩展:

never 是所有类型的子类型, 下面有网上别人对never 的巧妙运用: 类型扩张

类型扩张: 对于一个接口,如何定义某个属性为number ,其它不确定的属性都为string

如果像下面这么写会报错, 因为下面有类型限制

typescript
interface IType {
	age: number;
	[key: string]: string;
}

但是可以使用多一个接口来实现, 具体为:

typescript
interface ITypeAge {
  age: number;
}  
 
interface ITypeKeyAny {
  age: never;
  [key: string]: string;
}
 
type Itype = ITypeAge | ITypeKeyAny;
const demo: Itype = {
  age: 123,
  name: '000'
}

5. | ​

联合类型运算符,表示取值可以是多种类型中的一种,联合类型常与null或undefined一起使用, 也可以用在type 的定义中.

  • Interface类型的交叉
typescript
interface Interface2 {
  c: string;
  d: string;
}
interface Interface3 {
  c: string;
  e: string;
}
type Z2 = Interface2 | Interface3
// 满足其中一个接口的类型就行
let z2: Z2 = {
  e: '000',
  d: '000',
  c: '000',
}
  • Type类型的交叉
typescript
type Env1 = 'prod' | 'test' | 'dev';
type Env2 = 'prod' | 'boe' | 'ppe';
type EnvInter = Env1 & Env2;  // 'prod' | 'test' | 'dev' | 'boe' | 'ppe'

如果两者同名属性的类型有冲突, 该属性的类型是never .

6. <Type> ​

类型断言,在编译时起作用, 类似于as.

typescript
let someValue: any = "this is a string";
let strLength1: number = (<string>someValue).length;
let strLength2: number = (someValue as string).length;

7. _ ​

数字分割符,不会改变字面量的值,用于逻辑分组便于阅读.

typescript
const inhabitantsOfMunich = 1_464_301; // 1464301

. # ​

私有字段,在class中使用

  • 私有字段必须以#开头
  • 每个私有字段名称都唯一地限定于其包含的类
  • 不能在私有字段上使用Typescript可访问性修饰符,如:public或private
  • 私有字段不能在包含的类之外访问,甚至不能被检测到
typescript
class Person {
  #name: string;

  constructor(name: string) {
    this.#name = name;
  }

  greet() {
        console.log(`${this.#name}!`);
  }
}

let semlinker = new Person("Semlinker");

. typeof ​

  • 查询变量/属性的类型

typeof 只能用来查询变量或者属性的类型, 无法查询其他形式的类型. 比如说:返回调用的类型.

  • 获取对应的类型对象, 如
typescript
const info = {
  name: '000',
  age: 18,
  address: {
    street: 's1'
  }
}
type Info = typeof info
  • 结合keyof 使用, 获取枚举类型的具体属性名
typescript
enum HttpMethod {
  Get,
  Post
}
type Method = keyof typeof HttpMethod
  • 获取函数的传参和返回值类型
typescript
function add(a: number, b: number): number {
  return a + b
}
type AddType = typeof add
type AddReturnType = ReturnType<AddType>
type AddParamsType = Parameters<AddType> // 返回的是一个元组

10. as const ​

这里的as const 和js 里面的不太一样, js 里面是用来定义变量使用的, 这里可以看做是修饰符, 修饰过的变量不能再进行更改

typescript
let x = "hello" as const;
type X3 = typeof x; // type X = "hello"

let y = [10, 20] as const;
type Y3 = typeof y; // type Y = readonly [10, 20]

let z = { text: "hello" } as const;
type Z = typeof z; // let z: { readonly text: "hello"; }

// A 'const' assertions can only be applied to references to enum members,
// or string, number, boolean, array, or object literals.
// let a = (Math.random() < 0.5 ? 0 : 1) as const; // error

let b = Math.random() < 0.5 ? 0 as const :
  1 as const;

11. keyof ​

keyof 主要是用来获取某种类型的所有键,其返回类型是联合类型

typescript
const COLORS = {
  red: 'red',
  blue: 'blue'
}

// 首先通过typeof操作符获取Colors变量的类型,然后通过keyof操作符获取该类型的所有键,
// 即字符串字面量联合类型 'red' | 'blue'
type Colors = keyof typeof COLORS
let color: Colors;
color = 'red' // Ok
color = 'blue' // Ok

// Type '"yellow"' is not assignable to type '"red" | "blue"'.
// color = 'yellow' // Error

12. in ​

该操作符主要是用来遍历类型, 常见的应用如下所示

typescript
type Keys = 'a' | 'b' | 'c';
type Obj = {
  [ T in Keys]: string;
}
// in 遍历 Keys,并为每个值赋予 string 类型

// type Obj = {
//     a: string,
//     b: string,
//     c: string
// }

type roles = "tester" | "developer" | "manager";
const staffCount: { [k in roles]: number } = {
  tester: 100,
  developer: 200,
  manager: 300,
};