一、Typescript 是什么
1.1 Typescript是Javascript的超集, 可以解决大型项目的代码复杂性.
1.2 在编译期间就可以发现错误
1.3 强类型, 支持静态类型和动态类型
1.4 支持模块, 泛型和接口
二、Typescript 类型
布尔类型 boolean 只有ture/false
let isDone : boolean = true
数字类型 number 可为进制数
let numberVal: number = 1
字符串类型 string
let stringVal: string = '岁数'
symbol类型
const sym = Symbol()
数组类型
两种方式声明
变量名: 类型[]
let listNum: number[] = [1, 2, 3]
变量名:Array 泛型数组
let listStr : Array<string> = ['a', 'b', 'c']
let listO : Array<any> = [12, '12']
枚举类型 enum
数字枚举
enum Diraction {
MOTH,
COTH,
ATH
}
字符串枚举
enum DiractionStr {
MOTH = 'moth',
COTH = 'coth',
ATH = 'ath'
}
异构枚举
enum DiractionOr {
MOTH = 'moth',
COTH = 1,
ATH
}
常量枚举 编译结果不同
const enum DiractionCon {
MOTH,
COTH,
ATH
}
let conEnum: DiractionCon = DiractionCon.MOTH
any 类型
任何类型都可以被归为any类型, any 类型被称为全局超级类型
let anyVal : any = 66
anyVal = 'ST'
anyVal = [1, 2, 3]
anyVal = true
也可以将类型为any的值赋值给其他类型的值
let stringVal1 : string = anyVal
console.log(stringVal1);// true
console.log(typeof stringVal1) // boolean
我们可以对any类型的值进行任何操作,使用字数字,符串,数组等类型的方法
anyVal.toSting()
anyVal.splice(1)
unknown 类型(3.0引入)
unknown类型和any类型一样,所有类型都可以赋值给unknown
let unknownVal : unknown
unknownVal = '111'
unknownVal = 222
unknownVal = [1, 2, 3]
unknown类型的值只能赋值给any类型或者unknown类型的值
let unknownB : unknown
let unknownC : unknown = unknownB
let anyValA : any = unknownB
let strValUn : string = unknownB error
同时Unknown类型的值 不能使用任何类型的方法
unknownB.splice(1) //error
tuple 类型(元组)
固定长度,固定类型的数组 类型要一一匹配
let tupleType: [string, boolean];
tupleType = ["semlinker", true];
void 类型
void 类型和any相反,它表示没有任何类型,当一个函数没有返回值时,可以声明返回值类型为 void
function demo(): void {
console.log('no return')
}
声明一个值为void类型的值,它的值在严格模式下,只能为undefined, 没有任何意义
let voidVal : void = undefined
let voidVal : void = '111' error
null类型和undefined类型
let u : undefined = undefined;
let n : null = null;
Never 类型
never 类型表示的是那些永不存在的值的类型。 例如,never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型。 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) { }
}
在 TypeScript 中,可以利用 never 类型的特性来实现全面性检查, 要去吧Foo的值全部检测
type Foo = string | number;
function controlFlowAnalysisWithNever(foo: Foo) {
if (typeof foo === "string") {
// 这里 foo 被收窄为 string 类型
} else if (typeof foo === "number") {
// 这里 foo 被收窄为 number 类型
} else {
// foo 在这里是 never
const check: never = foo;
}
}
三、Typescript 断言
类型断言
1."尖括号"语法
let someVal = 'this is string'
let strLength : number = (<string>someVal).length
2.as 语法
let someValA = 'this is string'
let strLengthA : number = (someVal as string).length
非空断言 (现在没有?)
在无法判断类型时, 可以'!'来断言操作非 undefined类型和 非 null类型
具体写法 x! 将从x的值中排除 undefined 和 null
function handler(arg: string | null | undefined) {
let str: string = arg!;
}
确定赋值断言 (现在没有?)
允许在实列属性和变量后面添加 ! 号, 告诉ts该属性或变量会被明确赋值
具有初始值设定项的声明不能同时具有明确赋值断言
let x: number;
initialize();
// Variable 'x' is used before being assigned.(2454)
console.log(2 * x); // Error
function initialize() {
x = 10;
}
四、类型守卫
in 关键字
interface A2 {
A: number
}
interface A3 {
B: number
}
function test(a: A2 | A3) {
if ("A" in a) {
//确定类型为A
}
}
typeof 关键字(同JS的typeof)
function a(a: number | string | boolean): number {
if (typeof a == "string") {
//a.length
//可以使用字符的方法
} else if (typeof a == "number") {
// 可以使用number的方法
} else {
//可以使用布尔值
}
return 1
}
instanceof 关键字(同JS的instanceof)
class A {
name: string = "1"
}
class C {
name1: string = "222"
}
function AM(param: A | C) {
if (param instanceof A) {
// param.name
//可以使用A的属性和方法
}
}
自定义类型保护 is 一般用于函数返回值类型
function isNumber(x: any): x is number {
return typeof x === "number";
}
function isString(x: any): x is string {
return typeof x === "string";
}
五、Typescript 函数
Typescript函数含有类型,必填和可选参数,有函数类型,函数重载
函数类型
function add(x: number, y: number): number {
return x + y;
}
为函数返回值定义类型
可选参数和默认参数
可选参数
function buildName(firstName: string, lastName?: string) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
默认参数
function buildName(firstName: string, lastName = "Smith") {
return firstName + " " + lastName;
}
剩余参数
你想同时操作多个参数,或者你并不知道会有多少参数传递进来。 在JavaScript里,你可以使用 arguments来访问所有传入的参数
在TypeScript里,你可以把所有参数收集到一个变量里:
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
六、Typescript 数组(同javascript)
数组解构
let x: number; let y: number; let z: number;
let five_array = [0, 1, 2, 3, 4];
[x, y, z] = five_array;
数组展开运算符
let two_array = [0, 1];
let five_array = [...two_array, 2, 3, 4];
数组遍历
七、Typescript 对象
对象解构
let person = {
name: "Semlinker",
gender: "Male",
};
let { name, gender } = person;
对象展开运算符
let person = {
name: "Semlinker",
gender: "Male",
address: "Xiamen",
};
// 组装对象
let personWithAge = { ...person, age: 33 };
// 获取除了某些项外的其它项
let { name, ...rest } = person;
八、联合类型和类型别名
联合类型
联合类型通常与 null 或 undefined使用
cosnt sayHel = (name : string | undefined) => {
<!-- dothing -->
}
let num: 1 | 2 = 1;
type EventNames = 'click' | 'scroll' | 'mousemove';
类型别名
类型别名用来给一个类型起个新名字
type myStr = string
九、交叉类型
多个类型合并为一个类型,用运算符&合并
基础类型合并
type myS = string
type myN = number
let value:myS & myN // never
合并后的类型为never,因为不会存在值的类型为string和number
同名基础类型的合并
interface A{
name:string,
age:number
}
interface B{
name : number,
sex:boolean
}
let p: A&B
p = {
name: "fdf", // error
age: 18,
sex: true
}
接口A B中都包括属性name,但是他们的类型不同,所以最后为never, 如果相同可以合并成功
同名非基础类型属性的合并
interface D { d: boolean; }
interface E { e: string; }
interface F { f: number; }
interface A { x: D; }
interface B { x: E; }
interface C { x: F; }
type ABC = A & B & C;
let abc: ABC = {
x: {
d: true,
e: 'semlinker',
f: 666
}
};
console.log('abc:', abc);