My Little World

TS 学习

数组

元素为同一类型

1
2
3
let list:number[] = [1,2,3]
或者
let list Array<number> = [1,2,3]

声明不同类型的元素就要用元祖

元祖 Tuple

已知数组个数和每个元素类型下进行声明的变量类型
如,我想定义一个变量是一个数组,第一项是字符串类型,第二项是数字

1
let x:[string,number]

后续对于相应位置的元素的使用基于该位置上元素的类型
新添加的元素类型可以为之前元素的任一类型,不能是其他类型

1
2
3
4
5
6
7
8
9
10
11
//结合解构
function f([first, second]: [number, number]) {
console.log(first);
console.log(second);
}
f(input);

type C = { a: string, b?: number }
function f({ a, b }: C): void {
// ...
}

枚举 enum

对js数据类型补充,可以通过key值互相使用

1
2
3
4
5
6
7
8
enum Color {Red, Green, Blue} //默认从0开始给元素编号
let c: Color = Color.Red; //访问元素返回值
console.log(c) ===>0

enum Color {Red = 1, Green, Blue=4,Yellow} //未赋值的依据赋值的前一个,加1
let c: Color = Color.Green;
console.log(c) ===>2 color.Yellow ===>5
let colorName: string = Color[2]; ===>'Green' Color[6]===>undefined //没赋值的为undefined

Any

任何类型
用于不确定变量类型,仅知道部分元素类型的数组或者避免对这些变量进行校验
区别对象Object类型,Object类型只允许赋值,不允许调用值上面的方法,any可以

void

没有任何类型,通常用于函数没有返回值

1
2
3
function warnUser(): void {
console.log("This is my warning message");
}

Null 和 Undefined

是所有类型的子类型,即该类型变量可以赋值给其他类型
但在指定了–strictNullChecks标记,null和undefined只能赋值给void和它们各自

Never

表示永不存在的值的类型
会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型
变量也可能是 never类型,当它们被永不为真的类型保护所约束时

never类型是任何类型的子类型,也可以赋值给任何类型
然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外
即使 any也不可以赋值给never

1
2
3
4
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}

Object

除基本类型(number,string,boolean,symbol,null,undefined)之外的类型

1
2
3
4
5
6
7
8
9
declare function create(o: object | null): void;

create({ prop: 0 }); // OK
create(null); // OK

create(42); // Error
create("string"); // Error
create(false); // Error
create(undefined); // Error

类型断言

防止ts编译时根据推断的变量类型进行判断
让ts根据设置的类型进行编译判断

1
2
3
4
5
6
7
8
9
10
11
12
const foo = {};
foo.bar = 123; // Error: 'bar' 属性不存在于 ‘{}’
foo.bas = 'hello'; // Error: 'bas' 属性不存在于 '{}'

interface Foo {
bar: number;
bas: string;
}

const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';

接口

一个描述对象用来描述需要的数据类型

描述参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
interface LabelledValue {
label: string;
color?: string;//在可选属性名字定义的后面加一个?符号,这个属性可传可不传
//可选属性的好处之一是可以对可能存在的属性进行预定义,好处之二是可以捕获引用了不存在的属性时的错误
readonly y: number;//属性名前用 readonly来指定只读属性
[propName: string]: any;//索引签名,表示LabelledValue可以有任意数量的属性,只要不是上面已经定义过的 ;结合as 可以避免额外属性检查
}

function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

LabelledValue接口就好比一个名字,用来描述上面例子里的要求。 它代表了有一个 label属性且类型为string的对象。

描述函数类型

1
2
3
4
5
6
7
8
9
interface SearchFunc {
(source: string, subString: string): boolean; //输入参数名,类型和返回值类型
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) { //参数名可以和SearchFunc定义的不同,因为只会检查对应位置类型
let result = source.search(subString);
return result > -1;
}

索引签名

描述了对象索引的类型,还有相应的索引返回值类型

1
2
3
4
5
6
7
8
interface StringArray {
[index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];

TypeScript支持两种索引签名:字符串和数字。
可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型的子类型。
这是因为当使用 number来索引时,JavaScript会将它转换成string然后再去索引对象。
也就是说用 100(一个number)去索引等同于使用”100”(一个string)去索引,因此两者需要保持一致。

继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Shape {
color: string;
}

interface PenStroke {
penWidth: number;
}

interface Square extends Shape, PenStroke {
sideLength: number;
}
let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

联合类型

联合类型表示一个值可以是几种类型之一。
我们用竖线( |)分隔每个类型,
所以 number | string | boolean表示一个值可以是 number, string,或 boolean。

type 和 interface 区别
函数写法
implements 和 extends