声明数组的两种方式
let x1: number[];
x1 = [1, 2, 3]; // 方式1
let x2: Array = [1, 2, 3]; // 泛型
元组的含义
let x3: [string, number]; // 确定数量和类型
x3 = ['12', 10];
枚举
enum Color { // 默认从0开始编码 ,或者从第一个数字开始递增
Red,
Green,
Blue
}
enum Color2 {
Red = 1,
Green,
Blue
}
let c2 = Color2[2]; // Green 获得key
any的使用
// any使用不清楚具体类型 如用户输入或第三方库
let a: any = 11; // 直接通过类型检查
void 的使用
// void 没有任何类型 如函数返回值
function getMsg(): void {
return null || undefined; // void 可以返回null和undefined
}
null 和underfined
// null 和 undefined是所有类型的子类
let a: number = null; // 正常 但是指定strictNullChecks null和undefined只能赋值给自己
let b: number | null = null; // 此时可以使用联合类型
never 的使用
// never 永不存在的值的类型 总是会抛出异常或根本不会有返回值的函数的返回值类型。
// 变量也可以是never 被永不为真的类型约束
function errorFunc(): never {
throw new Error('test');
}
function fail(): never {
return errorFunc(); // 返回一个不会有返回值的函数执行
}
function loopFunc(): never {
while (true) {} // 无限循环
}
类型断言
// 类型断言 更了解某个值的详细信息 类似类型转换 只是编译起作用
let something = 'abs';
let strL: number = (something).length; // <> 方式一
let strL2: number = (something as string).length; // as 方式二
解构赋值声明
let arr = [1, 2];
let [a1, b1] = arr; // 解构数组 用的多的是解构对象 两边解构一致
function test2([first, second]: [number, number]) {} // 参数结构定义类型 前一个是参数 后一个是类型
test2([a1, b1]); // 传参必须是两个不能多个
test2(arr);
let obj = { a: 1, b: 2 };
let { a: obj1, b: obj2 }: { a: number; b?: number } = obj; // 重命名 后面的才是进行类型定义
function test3({ a = 1, b = 2 } = {}): void {} // 双重默认值 右边是没传参的默认值 左边是传参了但是某个字段没定义的默认值
let [first, ...rest] = [1, 2, 3, 4];
console.log(first);
console.log(rest); // [2,3,4] // 数组
let [m, , d, , e] = [1, 2, 3, 4, 5]; // 还可以空着
let obj3 = { a4: 1, b: 2 };
let obj4 = { ...obj3, a4: 1 }; // 从左往右处理,后面覆盖前面 展开仅可枚举 如obj里有方法则会丢失
只读属性
// 只读属性 只允许在初始的时候修改
interface ReadelonlyObj {
readonly x: number;
readonly y: number;
}
let readObj: ReadelonlyObj = { x: 10, y: 30 };
readObj.x = 50; // ERROR
let readArr = [1, 2, 3, 34, 45];
let ro: ReadonlyArray = readArr; // 只读数组
// ro不可重设置 不可扩展
字面量类型检查
interface SquareConfig {
color?: string;
width?: number;
}
function createSquare(config: SquareConfig) {
// ...
}
let mySquare = createSquare({ colour: 'red', width: 100 }); // Error 对象字面量会经过特殊检查 不能存在目标类型不存在属性
let sqare = { colour: 'red', width: 100 };
createSquare(sqare); // 正确检查 方法1
createSquare({ colour: 'red', width: 100 } as SquareConfig); // 类型断言正确 方法2
interface SquareConfig2 { // 方法三
color?: string;
width?: number;
[propName: string]: any; // 若确定带有任意数量的其他属性 可以添加字符串索引签名
}
函数声明
// 函数类型 使用interface来描述函数
interface FuncType {
(source: string, name: string): boolean;
}
let mySearch: FuncType;
mySearch = function (src: string, abc: string): boolean {
// 不要求名称一致 只要对应位置类型对上就行
return false;
};
// 函数 返回值类型一般省略, ts会自动推出
let myAdd: (x: number, y: number) => number = (
x1: number,
y1: number
): number => {
return x1 + y1; // 声明变量对函数类型 并不要求变量名一致
};
索引类型
interface StrArrType {
[index: number]: string; // 索引是number 值是string index只是一个代指 这样可以不确定数量
}
interface StrArrType1 {
readonly [index1: string]: number; // 规定了 string索引 返回值number readonly 可以防止赋值
}
let strArr: StrArrType = ['12', '2434']; // ts 支持 number 和 string当索引
class Animal {
name: string;
}
class Dog extends Animal {
breed: string;
}
// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
[x: number]: Animal; // 数字索引的返回值必须是字符串索引返回值的子类型 把animal 和dog调换类型都行 因为number索引是转换为string来索引的 这两者就冲突了
[x: string]: Dog;
}
接口复用
// 接口复用 一个接口可以继承多个接口
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
泛型
// 泛型可以表达 传入值和返回值是一致的 any 不可以 T捕获传入的变量
function testmm(a: Array): T {
return a;
}
testmm(1); //一般也没必要是用<>强制说明 ts会自动推论
// 缺点 必须使用通用属性 比如不能使用string.length 因为不确定类型
// 泛型类型
let masef:(arr:Array):T = testmm//具体实现