变量格式
//格式一
let 变量名: 变量类型 = 初始化值;
//格式二
let 变量名: 变量类型 | undefined;
变量名 = 变量值;
布尔类型
let flag: boolean = true;
console.log(flag);
数字类型
//整数型
let num: number = 123;
console.log(num);
//浮点型
let num: number = 3.1415926;
console.log(num);
字符串类型
let str: string = "Hello,TypeScript";
console.log(str);
数组类型
//第一种定义数组的方式,数字类型数组
let arr: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
console.log(arr);
//第二种定义数组的方式,数字类型数组
let arr: Array<number> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
console.log(arr);
元组类型
元组属于数组的一种,元组中允许存储不同类型的元素,数组中的元素必须是相同的类型。
let user: [number, string];
let userId = 10000;
let userName = "huhao";
let randomBoolean = true;
user = [userId, userName]; // 正确
user = [userId, randomBoolean]; // 错误
枚举类型
事先考虑到某一变量可能取的值,尽量用自然语言中含义清楚的单词来表示它的每一个值,这种方法称为枚举方法,用这种方法定义的类型称枚举类型。
TypeScript支持数字的和基于字符串的枚举
//枚举类型的定义
enum 枚举名 {
标识符[= 整型常数/字符串],
标识符[= 整型常数/字符串]
};
//枚举类型的示例
enum Flag {
success,
error,
overtime
};
let s: Flag = Flag.overtime;
console.log(s);//2
如果标识符没有赋值,它的值就是下标。
enum Flag {
success = 200,
error = 404,
overtime = 500
};
let s: Flag = Flag.overtime;
console.log(s);//500
如果标识符已经赋值,它的值就是被赋的值。
enum Flag {
success,
error = 100,
overtime
};
let s: Flag = Flag.overtime;
console.log(s);//101
如果标识符没有赋值,它的值就是下标,如果从中间突然指定了一个值,那么它之后的值都会从当前值开始重新计算。
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
let d: Direction = Direction.Up;
console.log(d);//UP
null类型
let n: null = null;
undefined类型
let u: undefined = undefined;
any类型
any 类型表示任意数据类型。
enum Flag {
success,
error,
overtime
};
let flag: any = true;//布尔型
let num: any = 123;//数字型
let str: any = 'Hello,TypeScript';//字符型
let arr: any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];//数组型
let tuple: any = [10086, 'Nick'];//元组型
let e: any = Flag.success;//枚举型
let n: any = null;//null型
let u: any = undefined;//undefined型
void类型
void 类型表示没有任何类型,一般用于定义方法的时候方法没有返回值。
function fn(): void {
console.log('执行成功了,我不需要返回值');
}
never类型
never 类型表示永远不存在的值的类型。
可以用来表示会抛出异常或根本不会有返回值的函数表达式或箭头函数表达式的返回值类型;
never 类型有以下特征:
1.never 是任何类型的子类型, 并且可以赋值给任何类型.
2.没有类型是 never 的子类型或者可以赋值给 never (除了 never 本身).
3.在一个没有返回值标注的函数表达式或箭头函数中, 如果函数没有 return 语句, 或者仅有表达式类型为 never 的 return 语句, 并且函数的终止点无法被执行到 (按照控制流分析), 则推导出的函数返回值类型是 never.
4.在一个明确指定了 never 返回值类型的函数中, 所有 return 语句 (如果有) 表达式的值必须为 never 类型, 且函数不应能执行到终止点.
使用 never 类型来表示不应该存在的状态
// TS推断出never类型,因为是不可能出现的
type bbb = string & number
// 因为必定抛出异常,所以 error 将不会有返回值
function error(msg: string): never {
throw new Error(msg)
}
// 因为存在死循环,所以loop将不会有返回值
function loop(): never {
while (true) {
}
}
never类型的一个应用场景
我们定义一个switch,都要定义一个default兜底逻辑,如果进入这一步,说明就是程序异常了
interface A {
type: "type1"
}
interface B {
type: "type2"
}
type All = A | B
function type(val: All) {
switch (val.type) {
case "type1":
break;
case "type2":
break;
default:
const check: never = val
break;
}
}
我新增一个C接口,我们必须手动找到搜有的switch代码并处理,否则将会触发bug
而且这将是一个“隐蔽性”的bug,如果回归面不够广,很难发现此类bug
那TS有没有办法帮助我们在类型检查阶段发现这个问题呢?
interface A {
type: "type1"
}
interface B {
type: "type2"
}
interface C {
type: "type3"
}
type All = A | B | C
function type(val: All) {
switch (val.type) {
case "type1":
break;
case "type2":
break;
default:
// 因为没有加入条件,所以会触发兜底函数并且会检测出异常
const check: never = val
break;
}
}
由于任何类型都不能赋值给never类型的变量,所以当存在进入default分支的可能性时,TS的类型检查会及时帮助我们发现这个问题
never 和 viod 的差异
// void类型只是没有返回值,但本身不会出错
function Fn1(): void {
console.log(123)
}
// 只会抛出异常没有返回值
function Fn2(): never {
throw new Error("error")
}
组合类型
ts 中支持一个变量可以赋予多种不同的变量类型,多个变量类型使用 |
分隔。
let num: number | null | undefined;
num = 3;
console.log(num);
num = null;
console.log(num);
num = undefined;
console.log(num);