Ts的运行:
安装TypeScript: npm install -g typescript
运行TypeScript执行命令: npm install -g ts-node
ts-node script.ts //执行某个ts文件
TypeScript概念:
TypeScript是javascript的一个超集,主要提供类型系统和对ES6的支持,它由Microsoft开发,代码开源于github。
安装使用TypeScript:
全局安装命令:npm install -g typescript
编译文件: tsc hello.ts
约定文件以.ts后缀,编写react时,以.tsx为后缀
数据类型:
原始数据类型:Javascript的类型分为两种:原始数据类型和对象类型。
原始数据类型包括:布尔值、数值、字符串、null、undefined以及ES6新类型symbol。
TypeScript原始数据类型:
string、number、boolean、null、undefined、enum、symbol。
空值一般采用void来表示,void可以表示变量,也可以表示函数无返回值。
TypeScript中的任意值:
任意值(Any)用来表示允许赋值为任意类型。
声明一个变量为任意值之后,对她的任何操作,返回值的内容的类型都是任意值。变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型。
TypeScript会依照类型推论的规则推断出一个类型,如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成any类型而完全不被类型检查。
原始数据类型:
let isDone:boolean = false;
let decLiteral: number = 6;
let myName: string = 'Tom';
let unusable: void = undefined;
let u: undefined = undefined;
let u: void;
let num: number = u;
任意值:
在任意值上访问任何属性都是允许的:
声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值。
let anyThing: any = 'hello';
变量如果在声明的时候,未指定其类型,那么它会被识别为任意值类型。
类型推论:
如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查。
联合类型:
联合类型(Union Types)表示取值可以为多种类型中的一种。
let myFavoriteNumber:string | number;
当 TypeScript 不确定一个联合类型的变量到底是哪个类型的时候,我们只能访问此联合类型的所有类型里共有的属性或方法。
访问 string 和 number 的共有属性是没问题的:
function getString(something: string | number): string {
return something.toString();
}
接口:
用接口(Interfaces)来定义对象的类型。
在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
定义的变量比接口少了一些属性是不允许的,多一些属性也是不允许的。
可选属性:
若我们希望不要完全匹配一个形状,那么可以用可选属性:
可选属性含义是该属性可以不存在
interface Person {
name:string;
age?:number
}
使用 [propName: string] 定义了任意属性取 string 类型的值。
一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集。
只读属性:
希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性。
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
id: 89757,
name: 'Tom',
gender: 'male'
};
只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候。
数组的类型:
数组类型有多种定义方式:
数组的项中不允许出现其他的类型。
数组的一些方法的参数也会根据数组在定义时约定的类型进行限制。
是使用「类型 + 方括号」来表示数组:
let fibonacci:number[] = [1,1,2,3,4];
数组的泛型:
使用数组泛型(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];
NumberArray 表示:只要索引的类型是数字时,那么值的类型必须是数字。
类数组:
类数组(Array-like Object)不是数组类型,比如 arguments:
arguments 实际上是一个类数组,不能用普通的数组的方式来描述,而应该用接口。
function sum() {
let args: {
[index: number]: number;
length: number;
callee: Function;
} = arguments;
}
any 在数组中的应用:
用any表示数组中允许出现的任意类型。
let list:any[] = ['xcatliu', 25, { website: 'http://xcatliu.com' }];
PS: 这里引入JS函数的知识。
两种常见的定义函数的方式——函数声明(Function Declaration)和函数表达式。
// 函数声明(Function Declaration)
function sum(x, y) {
return x + y;
}
// 函数表达式(Function Expression)
let mySum = function (x, y) {
return x + y;
};
一个函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到,其中函数声明的类型定义较简单:
输入多余的(或者少于要求的)参数,是不被允许的。
function sum(x:number,y:number):number{
return x+y;
}
函数表达式(Function Expression)的定义:
let mySum = function (x: number, y: number): number {
return x + y;
};
需要我们手动给 mySum 添加类型,则应该是这样:
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
let mySum2:(x:number,y:number) => number = function(x:number,y:number):number{
return x +y;
};
在ts的类型定义中,=》用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
用接口定义函数的形状
interface SearchFunc{
(source:string,subString:string):boolean;
}
let mySearch:SearchFunc;
mySearch = function(source:string,subString:string){
return source,search(subString) !== -1;
}
可选参数
与接口中的可选属性类似,我们用 ? 表示可选的参数。
function buildName(firstName: string, lastName?: string) {
if (lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');
可选参数必须接在必需参数后面。换句话说,可选参数后面不允许再出现必需参数了。
参数默认值
在 ES6 中,我们允许给函数的参数添加默认值,TypeScript 会将添加了默认值的参数识别为可选参数。
function buildName(firstName: string, lastName: string = 'Cat') {
return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');
此时就不受「可选参数必须接在必需参数后面」的限制了:
function buildName(firstName: string = 'Tom', lastName: string) {
return firstName + ' ' + lastName;
}
let tomcat = buildName('Tom', 'Cat');
let cat = buildName(undefined, 'Cat');
剩余参数
ES6 中,可以使用 ...rest 的方式获取函数中的剩余参数(rest 参数):
function push(array, ...items) {
items.forEach(function(item) {
array.push(item);
});
}
let a = [];
push(a, 1, 2, 3);
类型断言
类型:
语法:1.<类型>值 或 2. 值 as 类型(在 tsx 语法(React 的 jsx 语法的 ts 版)中必须用后一种。)。
将一个联合类型的变量指定为一个更加具体的类型。当TypeScript不确定一个联合类型的变量到底是哪个类型的时候,只能访问此联合类型的所有类型里共有的属性或方法。
使用类型断言,将something断言成string:
function getLength(something:string | number):number{
if((<string>something).length){
return (<string>something).length;
}else {
return something.toString().length;
}
}
类型断言的用法加上,在需要断言的变量前加上<Type>即可。
类型断言不是类型转换,断言成一个联合类型中不允许的类型是不允许的。
声明文件:
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型
declare let Talking: any; declare let Push: any; declare let cordova: any; declare let Swiper: any;
类型别名:
类型别名用来给一个类型起个新名字。使用 type 创建类型别名。
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
字符串字面量类型:
类型别名与字符串字面量类型都是使用 type 进行定义。
type EventNames = 'click' | 'scroll' | 'mousemove';
元组:
数组合并了相同类型的对象,而元组(Tuple)合并了不同类型的对象。
定义一对值分别为 string 和 number 的元组:
let tom: [string, number] = ['Tom', 25];
当赋值或访问一个已知索引的元素时,会得到正确的类型:
当赋值或访问一个已知索引的元素时,会得到正确的类型:
let tom: [string, number];
tom[0] = 'Tom';
tom[1] = 25;
tom[0].slice(1);
tom[1].toFixed(2);
当直接对元组类型的变量进行初始化或者赋值的时候,需要提供所有元组类型中指定的项:
let tom: [string, number];
tom = ['Tom', 25];
越界的元素:
当添加越界的元素时,它的类型会被限制为元组中每个类型的联合类型:
let tom: [string, number];
tom = ['Tom', 25];
枚举:
枚举(Enum)类型用于取值被限定在一定范围内的场景。
枚举使用 enum 关键字来定义:
enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
enum Test{
one = 1,
two,
three,
four
}
console.log(Test);
/*{ '1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
one: 1,
two: 2,
three: 3,
four: 4 }*/
一个枚举可以包含零个或多个枚举成员,枚举成员具有一个数字值,它可以是常数或计算得出的值。