TypeScript学习

TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持

好处:
-  在编译阶段就发现大部分错误,增加了代码的可读性和可维护性
- 可以定义从简单到复杂的几乎一切类型,TypeScript 编译报错,也可以生成 JavaScript 文件

缺点:
- 需要理解接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)等前端工程师可能不是很熟悉的概念
- 短期可能会增加一些开发成本,毕竟要多写一些类型的定义,不过对于一个需要长期维护的项目,TypeScript 能够减少其维护成本
- 集成到构建流程需要一些工作量

安装:
如果报错:
npm ERR! code UNABLE_TO_GET_ISSUER_CERT_LOCALLY
npm ERR! errno UNABLE_TO_GET_ISSUER_CERT_LOCALLY

执行npm config set strict-ssl false (关闭npm的https) 即可

ps:我们约定使用 TypeScript 编写的文件以 .ts 为后缀,用 TypeScript 编写 React 时,以 .tsx 为后缀。

基础:
	TypeScript 中,使用 : 指定变量的类型,: 的前后有没有空格都可以。
	function sayHello(person: string) {
	    return 'Hello, ' + person;
	}
	let decLiteral: number = 6;
	其中 ` 用来定义 ES6 中的模板字符串,${expr} 用来在模板字符串中嵌入表达式。
		let sentence: string = `Hello, my name is ${myName}.I'll be ${myAge + 1} years old next month.`


特点:
	1\JavaScript 没有空值(Void)的概念,在 TypeScript 中,可以用 void 表示没有任何返回值的函数:
		function alertName(): void {
		    alert('My name is Tom');
		}
		let unusable: void = undefined;
		
	2\任意值(Any)用来表示允许赋值为任意类型。如果是一个普通类型,在赋值过程中改变类型是不被允许的,而any可以.
	3\联合类型使用 | 分隔每个类型。let myFavoriteNumber: string | number;
	**4\对象类型**在 TypeScript 中,我们使用接口(Interfaces)来定义对象的类型。
		interface Person {//定义接口 Person
		    name: string;
		    age: number;
		}
		let tom: Person = {//定义了变量 tom,类型是 Person,tom的形状和 Person一致并不允许少或者多属性
		    name: 'Tom',
		    age: 25
		};
		**可选属性和任意属性**
		interface Person {//使用?是可选属性,只能少,不能多.,使用 [propName: string] 定义了任意属性取 string 类型的值。
		    name: string;
		    age?: number;
		    [propName: string]: any;
		}
		let tom: Person = {
		    name: 'Tom',
		    gender: 'male'
		};
		ps:需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集,
			即,使用了propName 那么age一旦存在,就不能用age:25
			
		只读属性
			interface Person {//只能在创建的时候被赋值,其余时间不能赋值.
			  readonly id: number;
			   name: string;
			   age?: number;
			   [propName: string]: any;
			}
	5\数组类型
		let fibonacci: (number | string)[] = [1, 1, '2', 3, 5];
		**也可以使用数组泛型(Array Generic) Array<elemType> 来表示数组:**
		let fibonacci: Array<number> = [1, 1, 2, 3, 5];
		
		用接口也可以描述数组
		interface NumberArray {
		    [index: number]: number;
		}
		let fibonacci: NumberArray = [1, 1, 2, 3, 5];
		只要 index 的类型是 number,那么值的类型必须是 number
		
		**any 表示数组中允许出现任意类型**
			let list: any[] = ['Xcat Liu', 25, { website: 'http://xcatliu.com' }];
	
	6\函数
		TypeScript需要把输入和输出都考虑到.PS:输入多余的或者少于的参数是不被允许的.
		function sum(x: number, y: number): number {
		   return x + y;
		}
		
		在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
		let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
		    return x + y;
		};
		
		**用接口的形式定义函数**
		interface SearchFunc {
		   (source: string, subString: string): boolean;
		}
		
		let mySearch: SearchFunc;
		mySearch = function(source: string, subString: string) {
		    return source.search(subString) !== -1;
		}
		
		**可选参数**
		同样用?,跟在冒号前面. 可选参数必须接在必需参数后面
		
		**参数默认值**
		TypeScript 会将添加了默认值的参数识别为可选参数,此时就不受「可选参数必须接在必需参数后面」
		function buildName(firstName: string = 'Tom', lastName: string) {
		    return firstName + ' ' + lastName;
		}
		
		**剩余参数**
		ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数),rest 参数只能是最后一个参数
		function push(array: any[], ...items: any[]) {
	    items.forEach(function(item) {
		        array.push(item);
		    });
		}
		let a = [];
		push(a, 1, 2, 3);
		
		**重载**
		允许一个函数接受不同数量或类型的参数时,作出不同的处理。以下可以做到:输入为数字的时候,输出也应该为数字,输入为字符串的时候,输出也应该为字符串。
		function reverse(x: number): number;
		function reverse(x: string): string;
		function reverse(x: number | string): number | string {
		    if (typeof x === 'number') {
		        return Number(x.toString().split('').reverse().join(''));
		    } else if (typeof x === 'string') {
		        return x.split('').reverse().join('');
		    }
		}
		重复定义了多次函数 reverse,前几次都是函数定义,最后一次是函数实现
		TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
	
	7\类型断言:在需要断言的变量前加上 <Type> 即可。
		<类型>值
			或
		值 as 类型(tsx中,即react中)
		function getLength(something: string | number): number {
		    if ((<string>something).length) {//类型断言,将something断言为string
		        return (<string>something).length;
		    } else {
		        return something.toString().length;
		    }
		}

声明文件

需要使用 declare var 来定义它的类型:
已经引入了jq不行,还需要声明 declare var : ( s e l e c t o r : s t r i n g ) = &gt; a n y ; 才 能 够 使 用 : (selector: string) =&gt; any; 才能够使用 :(selector:string)=>any;使(’#foo’);
declare var 并没有真的定义一个变量,只是定义了全局变量 jQuery 的类型

声明语句放到一个单独的文件(jQuery.d.ts)中,声明文件必需以 .d.ts 为后缀。
\\
其实可以用@types 统一管理第三方库的声明文件。
@types 的使用方式很简单,直接用 npm 安装对应的声明模块即可
npm install @types/jquery --save-dev
//
如果是以 npm install @types/xxx --save-dev 安装的,则不需要任何配置

全局变量的声明文件主要有以下几种语法:
declare var 声明全局变量,一般来说,全局变量都是禁止修改的常量,都应该使用 const 而不是 var 或 let。

declare function 声明全局方法,用来定义全局函数的类型。
	jQuery 其实就是一个函数,所以也可以用 function 来定义  declare function jQuery(selector: string): any;
	在声明语句中,重载也是支持的
	declare function jQuery(selector: string): any;
	declare function jQuery(domReadyCallback: () => any): any;
	jQuery('#foo');
	jQuery(function() {
	    alert('Dom Ready!');
	});

declare class 声明全局类,当全局变量是一个类的时候,我们用 declare class 来定义它的类型:		
	declare class Animal {
	    constructor(name: string);
	    sayHi(): string;
	}
	let cat = new Animal('Tom');
	
	declare class 语句也只能用来定义类型,不能用来定义具体的值,定义 sayHi 方法的具体实现则会报错:
	
		declare class Animal {
	    constructor(name: string);
	    sayHi() {
	        return `My name is ${this.name}`;
	    };
	    // ERROR: An implementation cannot be declared in ambient contexts.
	}

declare enum 声明全局枚举类型
declare namespace 声明全局对象(含有子属性)
interface 和 type 声明全局类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值