1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// js写法
let isBoolean = true;
let name = "zhangsan";
let age = 26;
let undef = undefined;
let n = null;
let stringArr = ["aaa", "bbb"];
// ts写法
let isBoolean: boolean = true;
let name: string = "zhangsan";
let age: number = 26;
let undef: undefined = undefined;
let n: null = null;
//两种形式都是可以表示预设类型为数组里面值类型为string
let stringArr: string[] = ["aaa", "bbb"];
let stringArr: Array<string> = ["aaa", "bbb"];
|
1
2
3
4
5
6
7
8
9
10
|
interface infClass={
a:string,
b?:number,
readonly c:boolean,
}
let infObject:infClass={
a:'1',
b:2,
c:false,
}
|
const 和 readonly 的区别
const 是在运行阶段进行检测,同时 const 如果定义的是复杂数据类型,可以更改地址里面的值但是不能改变引用的地址
readonly 实在编译阶段进行检测,他编译时如果发现对只读属性值的任何更改操作都会直接报错。
不清楚的类型
1
2
3
4
5
6
7
8
9
|
//看名字是number类型实际上鬼知道他是什么类型
let numberA: any = {
a: "1",
};
//需要注意any是绕过了所有的类型检查所以any类型可以被赋值给其他非any类型
let a: string = "类型检查";
let b: any = 0;
a = b; //b虽然不是string类型但是可以被赋值给a,因为any会绕过所有的类型检查
|
没有返回的函数
1
2
3
|
function setNumber(nunber: Number): void {
let a = number;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
// 尖括号形式声明
let anyValue: any = "hello word";
let anyLength: number = (<string>anyValue).length;
// as声明
let anyValue: any = "hello word";
let anyLength: number = (anyValue as string).length;
// 肯定化保证
let score: number;
startClass();
console.log(5 * score);
function startClass() {
score = 5;
}
let score!: number; // 告知编辑器,运行时会被赋值的
|
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
interface Teacher {
name: string;
courses: string[];
score: number;
}
interface Student {
name: string;
startTime: Date;
score: string;
}
type Class = Teacher | Student;
// in - 是否包含某种属性
function startCourse(cls: Class) {
//判断参数是那种类型
if ("courses" in cls) {
// 处理老师类型逻辑
}
if ("startTime" in cls) {
// 处理学生类型逻辑
}
}
// typeof / instanceof - 类型分类场景下的身份确认
function startCourse(cls: Class) {
if (typeof cls.score === "number") {
// 处理老师类型逻辑
}
if (typeof cls.score === "string") {
// 处理学生类型逻辑
}
}
function startCourse(cls: Class) {
if (cls instanceof Teacher) {
// 处理学生类型逻辑
}
if (cls instanceof Student) {
// 处理学生类型逻辑
}
}
// 自定义类型
const isTeacher = function (cls: Teacher | Student): cls is Teacher {
// 通过返回值判断是否是老师还是学生
};
const getInfo = (cls: Teacher | Student) => {
if (isTeacher(cls)) {
//如果是老师就返回老师的信息
return cls.courses;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//重点关注的是传入参数不同
function start(name: number, score: number): number;
function start(name: string, score: string): string;
function start(name: string, score: number): number;
function start(name: Comnbinable, score: Comnbinable) {
//通过类型守卫进行不同的处理
//同时如果传入参数类型不在重载的函数列表中,ts会编译报错
if (typeof name === "number" || typeof score === "number") {
// 处理
}
if (typeof name === "string" || typeof score === "string") {
// 处理
}
if (typeof name === "string" || typeof score === "number") {
// 处理
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
|
//注意,自由度越高后期维护成度越大,所以泛型和any一样慎用,用的太多会被人打的
function startClass<T, U>(name: T, score: U): T {
//此函数入参name要和返回参数类型一直,不然会报错
// 逻辑
}
function startClass<T, U>(name: T, score: U): string {
// 逻辑
}
function startClass<T, U>(name: T, score: T): T {
//断言
return (name + score) as T;
}
|
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
28
29
30
|
//定义一个校长装饰器
function principal(target: Function): void {
//给老师类额外增加监督老师的功能
target.prototype.supervise = function (): void {
// 逻辑
};
}
//相当于把整个tercher当做参数传递进了装饰器principal
@principal
class tercher {
constructor() {
// 业务逻辑
}
}
// 属性/方法装饰器
function isPrincipal(target: any, key: string): void {
//对传进来的参数进行数据劫持
Object.defineProperty(target, key, {});
}
class tercher {
constructor() {
// 业务逻辑
}
@isPrincipal
//劫持
public name: string;
}
|