TypeScript知识点总结

目录

TypeScript类型

原始类型

String

Array

Tuple

any

unknown

never

void

{}

Object

object

字面量类型

类型断言as

非空类型断言!

枚举enum

类型别名type

可选类型?

联合类型 |

匿名函数参数

 类型保护与类型缩小

this

函数的重载

接口interface

interface和type区别

freshness擦除

泛型

模块化开发

声明declare

TypeScript类型

原始类型

number、boolean、string、null、undefined、symbol

String

let msg: string = 'Hello world!';
let msg2: String = 'Hello world!';
let msg22 = 'Hello world!';  // 字面上没有定义类型
let msg3: String = new String('Hello world!');
 
console.log(typeof(msg));  // string
console.log(typeof(msg2));  // string
console.log(typeof(msg22));  // string
console.log(typeof(msg3));  // object
console.log(msg === msg2);  // true
console.log(msg === msg3);  // false
console.log(msg2 === msg3);  // false

与string的主要不同

1. 是一个String对象

2. 当使用eval()函数时,将被转换为字符串

let a: string = "3 * 9"
console.log(eval(a))

let b: String = new String("3 * 9")
// console.log(eval(b)) // Argument of type 'String' is not assignable to parameter of type 'string'
console.log(eval(b.toString()))

Array

const arr: string[] = ["aaa", "bbb", "ccc"]
const arr2: Array<string> = ["aaa", "bbb", "ccc"]
const arr3: (string | number)[] = ["aaa", 123]

如果添加其他类型到数组中会报错

Tuple

数组中通常建议存放相同类型的元素,而元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型

const info: [string, number, boolean] = ["aaa", 123, true]

any

表示任意类型, 可以是一个集合,里面包含了所有的类型

const arr: any[] = ["aaa", 111, true]

unknown

表示是是所有类型的父级

用于描述类型不确定的变量

所有基础类型都能赋值给unknown类型

const flag = true
let result: unknown

if (flag) result = "aaa"
else result = 111

any与unknown区别

const valueUnknown: unknown = "a"
let str: string = "str"
// str = valueUnknown // 报错

const valueAny: any = 123
let str2: string = "str2"
str2 = valueAny
console.log(typeof str2) // number 改变了str2的类型
console.log(str2) // 123

never

表示的是那些永不存在的值的类型

例如一个抛出异常的函数,一个永远不会返回的函数的返回值类型

never 类型是任何类型的子类型,可以赋值给任意类型。但是没有类型是 never 类型的子类型,即使是 any 类型也不能赋值给 never 类型

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
  throw new Error(message)
}
 
// 推断的返回值类型为never
function fail() {
  return error('Something failed')
}
 
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
  while (true) {}
}

void

用来指定一个函数没有返回值

可以将null或undefined赋值给void类型,也就是函数可以返回null或undefined

{}

描述了一个没有成员的对象

仍然可以使用在 Object 类型上定义的所有属性和方法,这些属性和方法可通过 JavaScript 的原型链隐式地使用

const typeObject: {} = {aaa: "aaa"}
// typeObject.aaa // 编译报错 Property 'aaa' does not exist on type '{}'
// console.log(typeObject["aaa"]) // 运行报错 Property 'aaa' does not exist on type '{}'

Object

类型 Object包括原始值

const obj: Object = "123" // OK

object

用于表示非原始类型

Object.create(proto);     // OK
Object.create(null);      // OK
Object.create(undefined); // Error
Object.create(1337);      // Error
Object.create(true);      // Error
Object.create("oops");    // Error

字面量类型

const text: "123" = "123"

一般与多个类型进行联合

type Alignment = "left" | "right" | "center"

类型断言as

有时候TypeScript无法获取具体的类型信息,这个时候我们需要类型断言

const myEl = document.getElementById("my-img") as HTMLImageElement

非空类型断言!

表示可以确定某个标识符是有值的,跳过ts在编译阶段对它的检测

枚举enum

枚举与字面量类型+联合类型组合的功能类似,都用来表示一组明确的可选值列表

enum Direction { Up, Down, Left, Right }
console.log(Direction.Up) // 0

类型别名type

type Point = {
	x: number
	y: number
}

可选类型?

在属性的后面添加?

可选类型可以看错是可选的类型和undefined的联合类型

联合类型 |

Union Type联合类型可以是由两个或者多个其他类型组成的类型

联合类型中的每一个类型被称为联合成员

类型A | 类型B | ......

匿名函数参数

当一个函数出现在TypeScript可以确定该函数会被如何调用的地方时,该函数的参数会自动指定类型

const strArr = ["aaa", "bbb", "ccc"]
strArr.forEach(item => {
    console.log(item.toUpperCase())
})

我们没有指定item的类型,但是item是一个string类型,这是因为TypeScript会根据forEach函数的类型以及数组的类型推断出item的类型

这个过程称之为上下文类型(contextual typing),因为函数执行的上下文可以帮助确定参数和返回值的类型

 类型保护与类型缩小

typeof

instanceof

in

平等缩小(===、!==)

this

1. 可以推导的this类型TypeScript不会报错

function sayHello() {
	console.log(this.name)
}
const info = {
	name: "why",
	sayHello() {
    	console.log(this.name) 
    }
}
info.sayHello()

2. 不确定的this类型TypeScript会在编译时报错

function sayHello() {
	console.log(this.name)
}
const info = {
	name: "why",
	sayHello
}
info.sayHello()

虽然我们能推导出来this的指向,但是对于TypeScript来说代码是非常不安全的,因为我们也有可能直接调用函数,或者通过别的对象来调用函数

3. 指定this的类型

type NameType = {
    name: string
}
function sayHello(this: NameType) {
    console.log(this.name)
}

函数的重载

function sum(a1: number, a2: number): number
function sum(a1: string, a2: string): string
function sum(a1: any, a2: any): any {
	return a1 + a2
}

1. 类的成员修饰符

public:默认,任何地方都ok

private:同一类

protected:自身以及子类

2. 只读属性readonly,不能被修改

3. get set获取设置私有属性

接口interface

也可以定义只读属性readonly

支持多继承extends

定义后可以被类实现

交叉类型在接口上的应用

interface Colorful {
    color: string
}

interface IRun {
    running: () > void
}
    
type NewType = Colorful & IRun

const obj: NewType = {
    color: "red",
    running() {}
}

interface和type区别

interface可以重复对某个接口定义属性和方法,只能为对象指定类型

type定义的是别名,别名不能重复,可以为任意类型指定别名

freshness擦除

将一个变量标识符赋值给其他的变量时,会进行freshness擦除操作

interface IPerson {
  name: string;
  age: number;
  eating: () => void;
}

const obj = {
  name: "czc",
  age: 22,
  height: 175,
  eating: function () {},
};

const person: IPerson = obj;

console.log(person); // { name: 'czc', age: 22, height: 175, eating: [Function: eating] }

// console.log(person.height); // Property 'height' does not exist on type 'IPerson'

泛型

// 泛型实现类型参数化
function foo<T, E>(a1: T, a2: E) {}

// 泛型接口
interface IFoo<T> {
    initialValue: T,
    valueList: T[],
    handleValue: (value: T) => void
}
    
// 泛型类
class Point<T> {
    x: T
    y: T
    
    constructor(x: T, y: T) {
        this.x = x
        this.y = y
    }
}

// 泛型约束
interface ILength {
    length: number
}

function getLength<T extends ILength>(args: T) {
    return args.length
}

模块化开发

TypeScript支持两种方式来控制我们的作用域

模块化:每个文件可以是一个独立的模块,支持ES Module、CommonJS

命名空间:通过namespace来声明一个命名空间

export namespace Time {
	export function format(time: string){
		return "2022-06-11"	
	}
}

声明declare

declare可以向TypeScript域中引入一个变量,在编写代码的时候就能够实现智能提示的功能

.d.ts 文件中的顶级声明必须以 "declare" 或 "export" 修饰符开头。

通过declare声明的类型或者变量或者模块,在include包含的文件范围内,都可以直接引用而不用去import或者import type相应的变量或者类型。

// 声明变量-函数-类
declare let wName: string
declare function wFoo(): void
declare class Person {}

// 声明模块
//  我们也可以声明模块,比如lodash模块默认不能使用的情况,可以自己来声明这个模块
// 在声明模块的内部,我们可以通过 export 导出对应库的类、函数等
declare module "lodash" {
    export function join(args: any[]): any
}

// 声明文件
// 比如在开发vue的过程中,默认是不识别我们的.vue文件的,那么我们就需要对其进行文件的声明
declare module "*.vue" {
    import { DefineComponent } from "vue"
    const component: DefineComponent

    export defualt component
}

// 声明命名空间
// 比如我们在index.html中直接引入了jQuery
declare namespace $ {
    function ajax(settings: any): void
}

参考资料

深入Vue3+TypeScript技术栈-coderwhy大神新课-学习视频教程-腾讯课堂

【TS】566- 一文读懂 TS 中 Object, object, {} 类型之间的区别_pingan8787的博客-CSDN博客

TypeScript declare_飞翔的熊blabla的博客-CSDN博客_declare typescript

TypeScript里string和String,真不是仅仅是大小写的区别_华为云开发者联盟的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值