TypeScript学习笔记

本文详细介绍了 TypeScript 的基础知识,包括变量声明、类型系统、数组、对象、接口、类、函数、模块和编译配置等。通过实例展示了如何利用 TypeScript 提升代码质量和可维护性,以及如何设置 tsconfig.json 文件实现自动编译。
摘要由CSDN通过智能技术生成

前述

什么是TypeScript

TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持,同时它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。


可以简单理解为 TS 就是 ES6 + 类型

TypeScript的优点
  1. 强类型语言增加了代码可读性和可维护性,可以在编译阶段就发现大部分错误
  2. 增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等
  3. 很好的包容性,.js文件可以直接重命名为 .ts文件,并且即使 TypeScript 编译报错,也可以生成 JavaScript 文件
  4. 兼容第三方库,即使第三方库不是用 TypeScript 写的,也可以编写单独的类型文件供 TypeScript 读取
准备
npm install typescript -g //用于将 ts 编译成 js
tsc --version //验证安装成功与否

类型

常见类型
/*布尔类型*/
let isDone: boolean = true;

/*数字类型*/
let count: number = 123;

/*字符串类型*/
let desc: string = "description";
let user = {name: "xiaoming", age: 18};
let desc: string = `hello, my name is ${user.name}, my age is ${user.age}`;

/*数组类型*/
let arr: Array<number> = [1, 2, 3];
let arr: number[] = [1, 2, 3];

/*元组类型*/
let tup: [string, number] = ['hello', 123];

/*Object类型(可以赋任意值,但是不能调用任意方法,即使它真的有)*/
//基本不用
let foo: object = { 
	name: "xiaoming",
	age: 18
}

/*对象类型(解决object类型无法推断问题)*/
let user: { 
	name: string, //必须有
	age: number //必须有
} = {
	name: 'xiaoming', 
	age: 18
}
//1. 某个属性可有可无
let user: {
	name: string,
	age?: number
}
user = {name: 'aaa'}
//2. 只能确定某些属性,其他不知道有哪些
let user: {
	name: string,
	[key:string]: unknown //键:string;值:任意
}
user = {
	name: 'aaa',
	say() {
		console.log(this.name)
	}
}
if (typeof user.say === 'function') user.say()

/*接口(解决对象类型无法复用问题)*/
interface Person {
	name: string,
	age: number
}
let user: Person = {
	name: 'xiaoming',
	age: 18
}

/*any类型(可以回归弱类型用法,尽量少用)*/
let num: any = 10;
num = '20';
let ret: string = (num as string).length //如此即可提示出string的相关属性和方法

/*void(表示没有任何类型)*/
function bar(): void { //表示没有返回值
	alert("hello typescript ~");
}
//声明一个void的变量,只能赋予undefined或null
let test: void = undefined;
let test: void = null;

/*null 和 undefined 类型*/
//和void一样,用于声明变量意义不大
let u: undefined = undefined;
let n: null = null;
//默认情况下undefined和null是所有类型的子类型,即可以将它们给如number类型赋值
//但是如果指定了 --strictNullChecks 标记,它们只能赋值给 void 以及它们自身。

/* unknown:表示一个未知类型 */
//1. 声明与基本用法
let a: unknown
a = 1
a = true
a = 'hello'
//2. 赋值
let a: unknown = '123'
let b: string
b = a //报错,指定了类型后,虽然字面上都是string,但无法这样直接赋值
if (typeof a === 'string') b = a //这样就可以
b = a as string //这样也可以
字面量声明
//字面量:客观存在的无法改变的值
//如:1,2,3,true,'hello'

let num: 23 //相当于const num = 23,即使用字面量声明后 num 的值为常量23
Enum类型
enum sex {
	MAN, WOMAN
}
console.log(sex.MAN) //0,默认第一个常量赋值为0,后面常量自增【同C语言】

enum sex {
	MAN = 3, WOMAN
}
console.log(sex.WOMAN) //4

enum sex {
	MAN='男', //非数字情况下,必须所有枚举值都要进行赋值
	WOMAN='女'
}
联合类型声明
/* 用 | 进行联合类型声明 */
//1.表示param可以是这几种类型中的任意一种
let param: number | string | boolean 
param = 123
param = '123'
param = true
//2.用于字面量
let param:12|13|14
param = 12
param = 13
param = 14
类型别名
type type1 = 1|2|3
let a: type1
let b: type1

解构

/*数组解构*/
let input = [1, 2]; //会自动进行类型推断(返回值也可以类型推断)
let [first, second] = input; //相当于 first=input[0]; second=input[1]

//交换变量
[first, second] = [second, first]; //相当于 let temp = first; first = second; second = temp;

//参数解构
function f ([first, second]: [number, number]) {
    console.log(first);
    console.log(second);
}
f([1, 2]);

//剩余参数解构
let [first, ...rest] = [1, 2, 3, 4, 5]
console.log(first) //1
console.log(rest) //[ 2, 3, 4, 5 ]

//忽略其他参数
let [first] = [1, 2, 3, 4, 5]
console.log(first) //1

//跳过一些参数
let [, second, , fourth, ] = [1, 2, 3, 4, 5]
console.log(second) //2
console.log(fourth) //4

//数组展开操作符
let arr1 = [1, 2, 3]
let arr2 = [...arr1, 4, 5, 6] //1, 2, 3, 4, 5, 6,实际是转换成了 concat 操作
/*对象解构*/
let o = {
	a: "foo",
	b: 12, 
	name: "bar"
}
let {b, name: c} = o //name是关键字,这里重命名为c
console.log(b, c) //12 bar

//剩余成员
let o = {
    a: "foo",
    b: 12,
    c: "bar"
}
let {a, ...others} = o
console.log(a, others.b + others.c.length) //foo 15

//默认值
function f(o: {a: string, b?: number}) {
	let {a, b = 1002 } = o;
}

//对象展开操作符
let o2 = {
	...o,
	d: 90,
	e: ""
}

基本用法
/*原本构造函数写法*/
function Person(name: string, age: number) {
	this.name = name;
	this.age = age;
}
Person.prototype.sayHello = function(): void {
	console.log(this.name, this.age)
}
let p = new Person("张三", 19)
p.sayHello()

/*ES6写法*/
class Person {
	name: string;
	age: number;
	constructor(name: string, age: number) { //类的构造函数(new时会自动调用)
		this.name = name;
		this.age = age;
	}
	sayHello(): void {
		console.log(this.name, this.age);
	}
}
let p = new Person("张三", 19);
p.sayHello();
类的继承
class Person {
    name: string;
    age: number;
    constructor(name: string, age: number) { //只能有一个构造函数
        this.name = name;
        this.age = age;
    }
    sayHello(): void {
        console.log(this.name, this.age);
    }
}

class Student extends Person {
    constructor(name: string, age: number) {
        super(name, age);
    }
}

new Student("小明", 19).sayHello();
简写方式
class Person {
    name: string;
    age: number;
    sex: number;
    constructor(name: string, age: number, sex: number) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
}

//等价于以下的简写方式(可混写):
class Person {
	sex: number;
	constructor(public name: string, public age: number, sex: number) {
		this.sex = sex; //混写
	}
}
getter & setter
class Person {
	/**
	 * 1. 注意需要在属性前加上 _
	 * 2. !:非null和非undefined的类型断言
	 */
    private _name!: string;
    
    get name() {
        return this._name;
    }
    set name(name: string) {
        this._name = name
    }
}
let person = new Person();
person.name = "小明" //set方法
console.log(person.name) //get方法
修饰符

修饰符书写有先后顺序:访问 -> 静态 -> 只读

访问修饰符
public:公开的,谁都能用(默认publicprotected:受保护的,仅类和类的子类能使用
private:私有的,仅类中才能使用(无法被继承)
静态修饰符
static:通过static修饰的成员叫静态成员,静态成员无需实例化,直接通过类名调用
只读修饰符
readonly:表示只可读,不可写(作用和const修饰的常量类似)
/*
1. 可以在声明同时赋予初始值
2. 可以在构造函数中赋值或者修改初始值
*/

class foo {
	public readonly desc: string = 'this is a demo.'
}

函数

参数与返回值
function demo(x: number, y: number): number {
	return x + y
}

/* 返回值: void */
//可以返回 空、null、undefined

/* 返回值: never */
//什么都无法返回
可选参数
function demo(x: number, y?: number): number {
	return x + 10
}
默认值
function add(x: number, y: number = 10) {
    return x ** 2 + y;
}
console.log(add(3)) // 3*3 + 10 = 19
console.log(add(3, 20)) //3*3 + 20 = 29
可变参数
function add(...nums: number[]) {
    return nums.reduce((previous, current) => previous + current);
}
let sum = add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
console.log(sum) //55
箭头函数
let add = (x: number, y: number): number => x + y

循环

for

同 js

for (let i = 0; i < 5; i++) {
    console.log(i)
}
forEach

不支持 break

[1, 2, 3].forEach((value, index) => {
    console.log(index, value)
})
for in

会将数组当做对象来遍历

let arr: number[] = [1, 2, 3]
for (const arrKey in arr) {
    console.log(arr[arrKey]) //1, 2
    if (arr[arrKey] == 2) break
}
for of

支持 break

let arr: number[] = [1, 2, 3]
for (const number of arr) {
    console.log(number) //1, 2
    if (number == 2) break
}

模块

导出
export default xxx //导出默认成员
export const foo: string = 'bar' //导出指定成员
export const bar: string = 'bar' //导出指定成员
导入
import xxx from '模块标识' //导入默认成员
import {foo, bar} from '模块标识' //导入指定成员

tsconfig.json

自动编译

只要包含tsconfig.json文件,在该文件所在目录中执行tsc -w //w表示实时监控,这样就会自动对该目录及各级子目录中所有的ts文件编译为js文件

配置选项
{
  "compilerOptions": {
    "allowJs": false, //是否对js进行编译,默认false
    "checkJs": false, //是否检查js语法规范,默认false
    "removeComments": false, //在编译时是否移除注释,默认false
    "noEmit": false, //不生成编译后的文件(只进行语法检查),默认false
    "noEmitOnError": false, //当存在语法错误时不生成编译后的文件,默认false
    "alwaysStrict": false, //编译后的js文件是否启用strict严格模式,默认false
    "noImplicitAny": false, //不允许隐式的any类型,默认false(function add(a, b){return a+b} //a和b即为隐式的any类型)
    "strictNullChecks": false, //严格的检查空值,默认false
    "target": "esnext", //编译后的js目标版本,可选[ES5 / ES2015, ES6 / ES2016, ES2017 / ESNext]
    //指定要使用的模块化规范,可选[None, CommonJS, AMD, System, UMD, ES6等]
    // - 其中只有 AMD和System 能和 --outFile 一起使用
    // - 其中ES6和ES2015 可使用在目标输出为ES5或更低的版本的情况
    "module": "esnext",
    "strict": true, //所有严格模式的总开关,默认false(可控制如strictNullChecks、noImplicitAny、alwaysStrict等)
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env"
    ],
    "paths": {
      "@/*": [
        "src/*"
      ]
    },
    //指定编译过程中需要引入的库文件列表
    // - 如果没有指定,则根据不同的target,有以下默认值
    // - - target ES5:DOM, ES5, ScriptHost
    // - - target ES6:DOM, ES6, DOM.Iterable, ScriptHost
    "lib": [
      "esnext",
      "dom",
      "dom.iterable",
      "scripthost"
    ],
    "outDir": "./dist", //指定编译后文件所在的目录(会自动创建)
    "outFile": "" //将所有编译后的文件合成一个文件并输出(会自动创建)
  },
  "include": [ //需要编译的ts文件所在的目录,默认[**/**],**表示任意目录,*表示任意文件,a/**/*表示a下的所有文件
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx"
  ],
  "exclude": [ //不需要编译的目录,默认["node_modules", "bower_components", "jspm_packages"]
    "node_modules"
  ],
  "extends": "./config/base.json", //表示继承(包含)base.json中的所有配置信息,后缀可省略
  "files": ["指定具体要编译的ts文件列表.ts"]
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值