Typescript学习日记,typescript从基础到进阶(第一章)

写在开头

最早接触typescript还是为了应付面试,当时还是在B站上看的尚硅谷的免费教程,看完了就没有然后了。后来进了比较大的公司,老大给我分享了一套typescript教程视频,想着正好借这个机会好好整理一下笔记然后分享出来。这东西网上很多,但是只有自己写的才是自己的,要是能混到路过的大佬指正错误就是真正赚到了。

说回正题,这个系列我会一直写下去,从typescript最基础的内容写到稍微高级一点的应用。但是有些内容我可能不会写太详细,比如类,tsc配置等
官网地址就不贴了,这里贴另外一个我觉得很不错的内容

https://github.com/typescript-cheatsheets/react

用到react的大佬们可以看看


正文

notion地址

https://seasoned-quasar-8c8.notion.site/3eac7a9975254063b989edb7b2a1c31a

为何学习typescript

定义:typescript是JavaScript的超集,需要编译成JavaScript才能在浏览器上运行

优势:

  1. 能够在开发过程中发现潜在的问题
  2. 更好的代码提示
  3. 更好的代码语义,使代码更加易于阅读

基础知识

类型注解和推断:

  • 类型注解:type annotation,告知typescript变量类型
  • 类型推断:type inference,TS自行推断变量类型

静态类型(同JavaScript,JavaScript是动态类型):

  • 基础类型:null,undefined,symbol,boolean,void,number,string
  • 对象类型:Object,Array,Function

基础用法

在变量后面添加冒号+类型

函数:

函数还涉及参数的类型,返回值的类型,写法并无太大区别,只是在使用解构时需要注意一下语法规则

const ff = ({num1, num2}: {num1: number, num2: number}) => {
}

返回值的类型需要写在括号之后

const ff = ({num1, num2}: {num1: number, num2: number}): number => {
  return 2
}

数组:

注解

数组的注解是小括号 + 中括号,其中小括号类限制数据类型

//数组的内容必须是字符串(括号是可以去掉的,下同理)
const arr: (string)[] = ['a', 'b', 'c']

//数组的内容必须是数字
const arr2: (number)[] = [1, 2, 3]

//数组的内容是字符串或者数字
const arr3: (string | number)[] = ['a', 'b', 1, 2]

需要注意一下多维数组的写法

const arr7: (string | number)[][] = [['a', 1]]
const arr8: (string)[][][] = [[['a']]]

对象类型注解:

//对象类型注解与数组的普通注解原理一致
const arr4: {name: string}[] = [{name: 'a'}]

多数情况下,使用类型别名进行这类的注解是更好的做法

type alias = {name: string, age: number}
const arr5: alias[] = [
  {name: 'a', age: 1},
  {name: 'b', age: 2},
]

当然,我们也可以使用class进行注解

class Student {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
}
const arr6: Student[] = [
  {name: 'a', age: 1},
  new Student('b', 2),
]

从上面的代码可以看出,class的注解并不需要new一个实例,ts会根据class的内容进行约束,在之前的ts版本中,这或许也是一种选择,因为下面这种写法并不会报错

class Student {
  name: string;
  age: number;
}

但在较新的ts版本中,这种写法并不被推荐

(property) Student.age: number
属性“age”没有初始化表达式,且未在构造函数中明确赋值。ts(2564)
元组

定义:写死的数组
用法:

const  tuple1: [string, number] = ['a', 1]
//等号前的代码规定了元组的长度,以及每一个位置的数据类型

对象新增关联用法

接口:

接口是TS中为了方便程序员而增加的一个工具,在TS编译成JavaScript后并不会有接口的代码痕迹

特性同其它编程语言中的接口基本一致,具有implements(实现),extends(继承)

interface Person {
  name: string,
}

type Person2 = {
  name: string,
}

const f1 = (person: Person) => {
  console.log(person.name)
}

const f2 = (person: Person2) => {
  console.log(person.name)
}

接口与类型别名的作用非常相似

interface Person3 = string //报错
type Person4 = string

区别在于,type能够直接代表基本类型,但是interface并不支持,需要在后面写一个对象
一般的建议是能写接口就尽量写接口,接口无法满足需要时再用类型别名

接口可选属性:
interface Person5 {
  name: string;
  age?: number;
}

当一个对象的某个属性并不是必要的时候,这时候我们需要将其标记为可选属性。写法是在冒号前面添加一个问号,这样TS会判定该属性在该类型对象中是可有可无的

只读属性:
interface Person6 {
  name: string;
  readonly age: number;
}
person.age = 12

(property) Person6.age: any
无法分配到 "age" ,因为它是只读属性。ts(2540)

在属性前面添加readonly,可以将其标记为只读属性,即不允许进行更改
只读属性可以与可选属性进行搭配

interface Person6 {
  name: string;
  readonly age?: number;
}
未知属性:
interface Person7 {
  name: string;
  [PropName: string]: any;
}
const person2: Person7 = {
  name: 'John',
  age: 36,
  gender: 'male',
}

当对象有不确定的属性的时候可以使用上面的写法,自带可选特性,也就意味着不能和?一起使用,但是可以和readonly搭配,使用场景较少

interface Person7 {
  name: string;
  readonly [PropName: string]: any;
}
const person2: Person7 = {
  name: 'John',
  age: 36,
  gender: 'male',
}
person2.name = 'Tom';
person2.age = 23

const person2: Person7
类型“Person7”中的索引签名仅允许读取。ts(2542)
方法属性:
interface Person8 {
  name: string;
  age: number;
  addAge: () => number;
  delName(): void;
}

或者纯定义函数

interface SaiHi {
  (word: string): void;
}
const say: SaiHi = () => {

}
其它:

在传递对象时,会遇到下面的情况

const person3 = {
  name: 'Tom',
  age: 23,
  gender: 'male',
  addAge: () => 2,
  delName: () => console.log('hello world')
}

const f3 = (person: Person8) => {
  console.log(person.name)
}
f3(person3)

在Person8中,并没有gender属性,但是上面的写法并不会报错
但是如果将写法改成下面这样时就会报错

f3({
  name: 'Tom',
  age: 23,
  gender: 'male',
  addAge: () => 2,
  delName: () => console.log('hello world')
})

类型“{ name: string; age: number; gender: string; addAge: () => number; delName: () => void; }”的参数不能赋给类型“Person8”的参数。
  对象文字可以只指定已知属性,并且“gender”不在类型“Person8”中。ts(2345)

因为通过字面量传递对象会触发TS的强校验

类:

private,protected,public特性与其它编程语言基本一致
类中的属性也支持添加readonly关键字

public,private,protected:
在类构造函数前添加这三个关键字时,相当于在类中声明了该属性,并且进行了初始化
class Person {
  constructor(public name: string) {}
}
const person = new Person('tom')
console.log(person.name)

//相当于
class Person {
	name: string
  constructor(name: string) {
		this.name = name
}
}
const person = new Person('tom')
console.log(person.name)
Getter,Setter:

类的getter和setter,可以用来获取类是私有属性或者赋值,它们的使用方法和一个普通的属性一致

class People {
  constructor(private _name: string) {}
  get name() { return this._name}
  set name(value: string) {
    this._name = value
  }
}
const people = new People('Tom')
console.log(people.name)
people.name = 'Jhon'
console.log(people.name)
单例实现:
class Demo {
  private static instance: Demo
  private constructor() {}
  static getInstance() {
    if(!this.instance) {
      this.instance = new Demo()
    }
    return this.instance
  }
}
const demo1 = Demo.getInstance()
const demo2 = Demo.getInstance()
console.log('demo2 === demo1: ', demo1 === demo2);
其它:

抽象类


类的知识基本一笔带过了,下一章会写个爬虫的实例,其实已经写完了,等我把第三章肝完了再放出来φ(゜▽゜*)♪

你可能感兴趣的:(typescript,typescript)