HOME
HOME
文章目录
  1. 1 安装
  2. 2 helloworld
  3. 3 数据类型
  4. 4 数组和元组
  5. 5 interface接口
  6. 6 函数
  7. 7 类型推论、联合类型、类型断言
  8. 8 类
  9. 9 枚举
  10. 10 泛型
  11. 11 交叉类型

typescript学习记录

1 安装

全局安装:npm install -g

2 helloworld

创建文件test.ts

1
2
3
4
const hello = (name: string) => {
return `hello ${name}`
}
hello("testme")

运行命令行tsc test.ts

生成test.js

1
2
3
4
5
var hello = function (name) {
return "hello " + name;
};
hello("testme");

string类型的限定并不会在js中产生新的代码,但是在tsc进行编译的时候,会有类型检查

将调用函数改为hello(123)

会报如下错误:

1
2
3
4
5
6
7
test.ts:7:7 - error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'.

7 hello(123)
~~~

Found 1 error.

但是test.js文件仍然生成了。

1
2
3
4
5
var hello = function (name) {
return "hello " + name;
};
hello(123);

3 数据类型

1
2
3
4
5
6
7
8
9
let isDone: boolean = false;
isDone = true;

let age: number = 10;
let firstname: string = 'testme';
let message: string = `hello, ${firstname}`;
let u: undefined = undefined;
let n: null = null;
let num: number = undefined;

null和undefined的区别

  1. 变量在还未初始化时,变量的默认值为undefined
  2. null表示尚未存在的对象,常用来表示函数返回一个不存在的对象。
  3. undefined是在null的基础上派生出来的,所以会判定为相等
1
2
3
console.assert(null == undefined)   // true
console.assert(null === undefined) //false
console.assert(typeof null == typeof undefined) //false

any类型

可以赋值为任意类型,可以调用任意方法及属性

1
2
3
4
5
let notSure: any = 4;
notSure = '123';
notSure = true;
notSure.myName;
notSure.getName();

const、let、var的区别

  1. const定义的变量不可以修改,而且必须进行初始化
  2. var定义的变量可以进行修改,不初始化会默认定义为undefined,不会报错
  3. let是块作用域,在函数内部使用let定义变量后,对函数外部无影响。

建议使用的优先级const > let > var

4 数组和元组

数组,存放的数据为同一类型

1
2
3
4
let arrofNumbers: number[] = [1,2,3];
arrofNumbers.length;
arrofNumbers.push(3);
console.log(arrofNumbers.length);

元组,存放的数据可以为不同类型

1
2
let user: [string, number,] = ['1234', 123]
user.push('123') // push的值只能是定义时候的两种类型

5 interface接口

定义:对对象的形状进行描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface IPerson{
readonly id: number; // 不可以变
name: string;
age?: number; // age属性为可选可不选

}

let viking: IPerson = {
id: 1,
name: 'viking',
age: 20
}

viking.id = 123; // 报错,为只读

6 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add(x: number, y: number): number {
return x + y;
}

const add2 = (x: number, y: number, z?:number): number => {
if (typeof z === 'number'){
return x+y+z;
}
return x + y;
}

interface ISum{
(x: number, y: number, z?:number): number //接口定义函数类型
}

let add3: ISum = add

7 类型推论、联合类型、类型断言

根据赋值的类型推断出变量的类型:

1
let str = 'sstr';

联合类型

1
2
3
4
5
let numberOrString: number | string;
numberOrString.length
numberOrString.toString // 只能访问联合类型中共有的属性或者方法
numberOrString = 123;
numberOrString = '123';

类型断言:在函数中断言该变量类型是什么类型,然后调用对应的方法

1
2
3
4
5
6
7
8
9
function getLength(input: string | number): number{
const str = input as string;
if (str.length){
return str.length
}else {
const num = input as number
return num.toString().length
}
}

另一种写法:

1
2
3
4
5
6
7
function getLength2(input: string | number): number{
if (typeof input === 'string'){
return input.length
}else {
return input.toString().length
}
}

8 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Animal{
name: string;
constructor(name) {
this.name = name
}
run(){
return `${this.name} is running`;
}
}

const snack = new Animal('test');

class Dog extends Animal{
bark(){
return `${this.name} is barking`;
}
}

const xiaobao = new Dog('xiaobao')

类实现接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface IRadio {
switchRadio(trigger: boolean): void;
}

interface IBattary{
checkBattaryStatus(): void
}

interface IRadioWithBattery extends IRadio{
checkBattaryStatus(): void
}

class Car implements IRadio{
switchRadio(trigger: boolean){

}
}


class CellPhone implements IRadioWithBattery{
switchRadio(trigger: boolean){

}
checkBattaryStatus() {

}
}

9 枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum Direction{
Up = 10,
Down,
Left,
Rigth,
} //首项进行赋值后,后续项进行递增

console.log(Direction.Left)
console.log(Direction[0])


const enum Direction{
Up = "Up",
Down = "Down",
Left = "Left",
Rigth = "Right",
} //常量枚举

10 泛型

根据我们传入的一个类型,返回一个类型

1
2
3
4
5
6
7
8
9
10
11
12
13
function echo<T>(arg: T): T{
return arg;
}

function echo2(arg){
return arg;
}

const str: string = "123";

const result = echo(str);

const result2 = echo2(str);
1
2
3
4
5
function swap<T, U>(tuple: [T, U]): [U, T] {
return [tuple[1], tuple[0]];
}

const res = swap(['string', 123])

约束泛型

提前在代码中使用对应类型的方法及属性。

通过接口定义来约束泛型

1
2
3
4
5
6
7
8
interface IWithLength{
length: number //鸭子模型,有该属性就行,名称无所谓
}

function echoWithArr2<T extends IWithLength>(arg: T[]): T[]{
console.log(arg.length)
return arg
}

泛型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Queue<T>{
private data = [];
push(item:T){
return this.data.push(item)
}
pop():T{
return this.data.shift()
}
}

const queue = new Queue<number>();
queue.push(1);
queue.push(2)
console.log(queue.pop().toFixed())
console.log(queue.pop().toFixed())

泛型接口

1
2
3
4
5
6
7
8
interface KeyPair<T, U>{
key: T,
value: U
}

let kp1: KeyPair<number, string> = {key: 1, value: 'str'}
let kp2: KeyPair<string, number> = {key: '1', value: 123}
let arr2: Array<number> = [1,2,3]

11 交叉类型

1
2
3
4
5
6
7
interface IName{
name:string
}

type IPerson = IName & { age: number} // 使用&将两个类型连接起来

let person: IPerson = {name: 'test', age: 123}