TypeScript学习笔记(上)

TypeScript学习笔记


命令:ts-node:可以直接运行ts文件,tsc:可以把ts文件转换成js文件

  • Static Typing
    TypeScript的一个最主要特点就是可以定义静态类型,英文名是Static Typing,就是类型定义后就不允许更改。

    const count: number = 1;
    count = 'string' 
    

    这就是简单的定义一个数字类型的count的变量,这里的: number 就是已定义了一个静态类型。这样定义后count这个变量在程序中就永远是数字类型了,不可以改变了。

    自定义静态类型
    你还可以自己去定义一个静态类型。

    interface People {
    	name: string,
    	age: number
    }
    const p: People = {
    	name: '张三',
    	age: 18
    }
    

    这时候你如果声明变量的类型,跟自定义不一样,vscode直接就会报错。需要的注意的是,这时候p变量也具有nameage属性了。
    如果使用了静态类型,不仅意味着变量的类型不可改变,还以为着类型的属性和方法也跟着确定了。这个特点就大大提高了代码的健壮性

  • TypeScript基础静态类型和对象类型
    在TypeScript静态类型分为两种,一种是基础静态类型,一种是对象类型。
    (1)基础静态类型非常简单,只要在声明变量的后面加一个:,然后加上对应的类型。例:

    const count : number = 918;
    const myName: string = 'string'
    

    类似这样常用的基础类型还有nullundefinedsymbolboleanvoid
    (2)对象类型

    const person: {
    	name: string,
    	age: number,
    } = {
    	name: '张三',
    	age: 18
    };
    console.log(person.name)
    

    对象类型也可以是数组。例:

    const personList: String[] = ['张三', '李四', '王五'];
    

    这时候变量personList必须是一个数组,数组里的内容必须是字符串。
    const personList: String[] = ['张三','李四',123];
    编译器会报错
    类形式:
    class Person{ }; const p: person = new Person();
    p必须是一个Person类对应的对象才可以。
    (3)函数类型

    const fun: () => string = () => {
    	return 张三‘;
    }
    

    总结
    对象类型有一下几种形式:

    • 对象类型
    • 数组类型
    • 类类型
    • 函数类型

    这几种形式在TypeScript里叫做对象类型

  • TypeScript中的类型注解和类型推断
    (1)类型注解 type annotation

    let count: number;
    count = 123
    

    这段代码的类型注解,已是是显式的告诉代码,我们的count变量就是一个数字类型,这就叫做类型注解
    (2)类型推断 type inference
    let countInferrence = 123;
    这时候我并没有显示的告诉你变量countInference是一个数字类型,但是TypeScript会自动帮你推断出countInference的类型是number
    (3)工作使用问题(潜规则)

    • 如果ts能够自动分析变量类型,我们就什么也不需要做了
    • 如果ts无法分析变量类型的话,我们就需要使用类型注解

    不用谢类型注解的例子:

    const one = 1;
    const two = 2;
    const three = one + two;
    

    需要些类型注解的例子:

    function getTotal(one, two) {
    	retrun one + two;
    }
    const total = getTotal(1, 2)
    

    这种形式就需要用到类型注解了,因为这里的onetow会显示为any类型。这时候如果你传字符串,你的业务逻辑就是错误的,所以必须加一个类型注解

    	function getTotal(one: number, two: number) {
    		return one + two;
    	}
    	const total - getTotal(1, 2);
    

    总结:
    TypeScript代码的一个重要宗旨就是每个变量,每个对象的属性类型都应该是固定的,如果能推断就让它推断,推断不出来就要加注解

  • TypeScript函数参数返回类型定义
    (1)简单类型定义

    function getTotal(one, two) {
    	return one + two;
    }
    const total = getTotal(1, 2);
    

    这时候我们写的代码其实是有一个小坑的,就是我们没有定义getTotal的返回值类型,虽然TypeScript会自己推断出返回值是number类型。但是如果这时候我们的代码写错了:

    function getTotal(one: number, two: number) {
    	return one + tow + '';
    }
    const total = getTotal(1, 2);
    

    这时候total的值就不是number类型了,但是不会报错。有的小伙伴这时候就会说,直接给total一个类型注解:

    const total: number = getTotal(1, 2);
    

    这样写虽然编译器会报错,但是这还不是很高明的算法,因为你没有找到错误的根本,这时候错误的根本是getTotal()函数的错误,所以适合的做法是给函数的返回值加上类型注解,代码如下:

    function getTotal(one: number, two: number): number {
    	return one + two;
    }
    const total = getTotal(1, 2);
    

    这段代码就比较严谨了,所以在写代码的时候尽量让自己的代码更加严谨。
    (2)函数无返回值时定义方法
    有时候函数没有返回值:

    	function sayHello() {
    		console.log('hello world');
    	}
    

    这段代码是没有返回值的,我们可以给他一个类型注解void,代表没有任何返回值

    	function sayHello(): void {
    		console.log('hello world');
    	}
    

    (3)never返回值类型
    如果一个函数永远也执行不完,就可以定义返回值为never,例:

    	function errorFuntion(): never {
    		throw new Error();
    		console.log('hello world');
    	}
    

    或者

    	function forNever(): never {
    		while(true){};
    		console.log('hello world');
    	}
    

    (4)函数参数为对象(解构)时
    JavaScript写法:

    	function add({one, two}) {
    		return one + two;
    	}
    	const total = add({one: 1, two: 2});
    

    添加类型注解:

    	function add({one, two}: {one: number, two: number}) : number {
    		return one + two;
    	}
    	const three = add({one: 1, two: 2});
    

    因为参数是一个对象,所以注解的应该是这个对象。

  • TypeScript中数组类型的定义
    (1)一般数组类型的定义

    	const number: number[] = [1, 2, 3];
    

    通过类型推断可以得出numberArr的类型:number[]
    或者:

    const stringArr: string[] = ['a', 'b', 'c'];
    

    可以推断出stringArr的类型为 string[]
    或者:

    const undefinedArr: undefined[] = [undefined, undefined];
    

    可以推断出undefinedArr的类型为any[]

    也可以包含多种类型:

    const arr: (string | number) = [1, 'a', 2];
    

    (2)数组中对象类型的定义

    const person: {name: string, age: number}[] = [
    	{name: '张三', age: 18},
    	{name: '李四', age: 20}
    ]
    

    这种形式看起来比较麻烦,而且如果有同样类型的数组,不可复用,TypeScript为我们准备了一个叫类别名(type alias)的东西,刚才代码可以这样写:

    type Person = {name: string, age: number};
    
    const person: Person[] = [
    	{name: '张三', age: 18},
    	{name: '李四', age: 20},
    ]
    

    类形式的写法:

    class Person {
    	name: string,
    	age: number
    }
    const person: Person[] = [
    	{name: '张三', age: 18},
    	{name: '李四', age: 20},
    ]
    
  • TypeScript中元组的使用和类型约束
    TypeScript中提供了元组的概念,这个概念是JavaScript中没有的。你可以把元组看成数组的一个加强,它可以更好的控制或者说规范里面的类型。
    (1)元组的基本应用

    const person = ['张三', '李四', 28]
    

    类型推断后,相当于

    const person: (string | number)[] = ['张三', '李四', 28];
    

    现在我们调换数组元素的顺序,TypeScript仍然不会报错:

    const person: (string | number)[] = ['张三', , 28 ,'李四'];
    

    所以,我们需要一个更强大的类型来解决这个问题
    元组和数组类似,但是类型注解时会不一样:

    const person: [string, string, number] = ['张三', , 28 ,'李四'];
    

    (2)元组的使用
    CSV文件提供数据格式使用逗号隔开例如:

    '张三', 'teacher', 19;
    '李四', 'doctor', 23;
    

    为了严格校验格式,我们就可以用到元组

    const person: [string, string, nuber] = [
    	{'张三', 'teacher', 19}
    	{'李四', 'doctor', 23}
    ]
    
  • TypeScript中的interface接口
    TypeScript中的接口就是用来规范类型的。
    (1)interface接口初步了解
    现在要做一个简历筛选的程序。年龄小于25岁,女。可以进入面试关节,代码如下:

    const filter = (name: string, gender: number, age: number) {
    	if(gender == 1) {
    		console.log(name + '进入面试');
    	} else {
    		console.log(name + '被淘汰');
    	}
    }
    filter('张三', 1);
    

    现在又加了个需求,就是必须能看到简历。代码如下:

    const getFilter(name: string, gender: number, age: number) => {
    	console.log(name + '性别是' + gender);
    	console.log(name + '年龄是' + age);
    }
    getFilter('张三', 1, 20)
    

    两个方法类型注解一样,需要做一个统一的约束。类型别名可以解决代码重复的问题,接口同样可以:

    @interface Person {
    	name: string,
    	gender: number,
    	age: number
    }
    
    const filter = (person: Person) => {
    	if(gender == 1) {
    		console.log(name + '进入面试');
    	} else {
    		console.log(name + '被淘汰');
    	}
    }
    const getFilter(person: Person) => {
    	console.log(name + '性别是' + gender);
    	console.log(name + '年龄是' + age);
    }
    
    const person = {
    	name: '张三',
    	gender: 1,
    	age: 20
    }
    filter(person);
    getFilter(person);
    

    (2)接口和类别名的区别

    • 类型别名可以直接给类型,比如string,而接口必须代表对象。
      例如:
    type person = string;
    

    但接口就不能这样写。
    (2)接口非必选值的定义

    interface person {
    	name: strig,
    	age: nuber,
    	waistline?: number,//要么不填 填的话必须是number类型的
    }
    

    (3)允许加入任意值

    interface Person {
    	name: string;
    	age: number;
    	gender: number;
    	[propname: string]: any;
    }
    
    const person = {
    	name: '张三',
    	age: 18,
    	gender: 1,
    	height: 170,
    	say(): string,
    }
    

    (4)接口和类的约束

    class zhangsan implements Person{};//这样会直接报错
    
    class zhangsan implements Person {
    	nam = '张三',
    	age = 18;
    	say() {
    		return 'hello world';
    	}
    }
    

    (5)接口间的继承

    interface Teacher extend Person {
    	teach(): string;
    }
    
  • TypeScript中类的概念和使用
    (1)类的基本使用

    class Lady {
    	content = 'hello world';
    	sayHello() {
    		return this.content;
    	}		
    }
    const goddess = new Lady();
    console.log(godess.sayHello);
    

    (2)类的继承
    TypeScript的继承和ES6中的继承是一样的。关键字也是extends,例:

    class Lady {
    	content = "hello world";
    	sayHello() {
    		return this.content;
    	}
    }
    class Teacher extends Lady{
    	sayHi() {
    		return 'hi world';
    	}
    }
    const godess = new Teacher();
    console.log(godess.sayHello());
    console.log(godess.sayHi());
    

    (3)类的重写

    class Lady {
    	content = "hello world";
    	sayHello() {
    		return this.content;
    	}
    }
    class Teacher extends Lady{
    	sayHi() {
    		return 'hi world';
    	};
    	sayHello() {
    		return 'hello haha';
    	};
    }
    const godess = new Teacher();
    console.log(godess.sayHello());
    console.log(godess.sayHi());
    

    (4)super关键字的使用
    super关键字的使用,子类可以直接调用父类的方法

    class Teacher extends Lady {
    	sayHi() {
    		return 'hi world';
    	};
    	sayHello() {
    		return 'hello haha';
    	};
    	saySuperHello() {
    		return super.sayHello();
    	}
    }
    const godess = new Teacher();
    console.log(godess.saySuperHello());
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值