typescript 类型相关

183 阅读3分钟

一: utility type一些工具type,返回的是一个type类型

1、type Pick<T,K extends keyof T> = { [P in K]: T[P] }

keyof T: 取出T中的所有key,变为一个联合类型,比如{name: string, age: number} => name | age extends: 必须是这个联合类型的子集,只能是name,或者 age 或者name | age

2、type Partial = { [P in keyof T]?: T[P] }; in: 可以理解为遍历

3、TypeScript 没办法像 JavaScript 那样访问 DOM。这意味着每当我们尝试访问 DOM 元素时,TypeScript 都无法确定它们是否真的存在。

const link = document.querySelector('a');
console.log(link.href); // ERROR: Object is possibly 'null'. TypeScript can't be sure the anchor tag exists, as it can't access the DOM

使用非空断言运算符 (!),我们可以明确地告诉编译器一个表达式的值不是 null 或 undefined。当编译器无法准确地进行类型推断时,这可能很有用:

// 我们明确告诉 TS a 标签肯定存在
const link = document.querySelector('a')!;

console.log(link.href); // conardli.top

这里我们没必要声明 link 变量的类型。这是因为 TypeScript 可以通过类型推断确认它的类型为 HTMLAnchorElement

但是如果我们需要通过 class 或 id 来选择一个 DOM 元素呢?这时 TypeScript 就没办法推断类型了:

const form = document.getElementById('signup-form');

console.log(form.method);
// ERRORObject is possibly 'null'.
// ERRORProperty 'method' does not exist on type 'HTMLElement'.

我们需要告诉 TypeScript form 确定是存在的,并且我们知道它的类型是  HTMLFormElement。我们可以通过类型转换来做到这一点:

const form = document.getElementById('signup-form'as HTMLFormElement;

console.log(form.method); // post

TypeScript 还内置了一个 Event 对象。如果我们在表单中添加一个 submit 的事件侦听器,TypeScript 可以自动帮我们推断类型错误:

const form = document.getElementById('signup-form'as HTMLFormElement;

form.addEventListener('submit'(e: Event) => {
  e.preventDefault(); // 阻止页面刷新

  console.log(e.tarrget); // ERROR: Property 'tarrget' does not exist on type 'Event'. Did you mean 'target'?
});

4、访问修饰符 我们可以给类的属性添加访问修饰符,TypeScript 还提供了一个新的 readonly 访问修饰符。

class Person {
  readonly namestring// 不可以变的
  private isCoolboolean// 类的私有属性、外部访问不到
  protected emailstring// 只能从这个类和子类中进行访问和修改
  public agenumber// 任何地方都可以访问和修改

  constructor(n: string, c: boolean, a: number) {
    this.name = n;
    this.isCool = c;
    this.age = a;
  }

  sayHello() {
    return `Hi,我是 ${this.name} ,我今年 ${this.age} 岁了`;
  }
}

const person1 = new Person('ConardLi'true'conard@xx.com'17);
console.log(person1.name); // ConardLi
person1.name = 'Jerry'// Error: read only

我们可以通过下面的写法,属性会在构造函数中自动分配,我们类会更加简洁:

class Person {
  constructor(
    readonly name: string,
    private isCool: boolean,
    protected email: string,
    public age: number
  ) {}
}

如果我们省略访问修饰符,默认情况下属性都是 public,另外和 JavaScript 一样,类也是可以 extends 的。

参考

4、 unknow 相比于 any 来说增加了一次自我断言

const a: any = 1;
a.split(); //实际上a没有split方法,但是它不报错。

const b:unknow = 'ac';
(b as string).split(); // unknow 会需要你自己增加一个断言。

5、类型断言

  • ts 类型收窄
type Rect = {
  height: number
  width: number
}
type Circle ={
  center: [number, number]
  radius: number
}
const f1=(a: Rect | Circle)=>{
  if(isRect(a)){
    // a 是Rect类型 这边收窄了a的类型为Rect
  }
}

// 必须写 x is Rect 不能写返回boolean类型 不然ts无法在上面判断a的类型。
function isRect(x: Rect | Circle): x is Rect {
  return 'height' in x && 'width' in x
}

function isCircle(x: Rect | Circle): x is Circle {
  return 'center' in x && 'radius' in x
}
  • 以下截图都是js逻辑来实现的收窄,众所周知js类型很垃圾。

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

6、ts中typeof的用法注意和js中的区分

image.png

7、as const

const a = ['abc']; // a => string[]
const a = ['abc'] as const; // a=> readonly ['abc']
    ```