typeScript是什么?
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持
安装typeScript
npm install -g typeScript
安装完成查看版本:
tsc -v
typeScript文件的后缀不是js而是ts,如何将ts文件转为js?
tsc test.ts
typeScript编辑器
Visual Studio Code 内置对typeScript的支持不需要在添加插件
Sublime Text 需要安装TypeScript-Sublime-Plugin插件
按下Ctrl+Shift+P调出命令面板,输入install 调出 Install Package 选项并回车,输入TypeScript-Sublime-Plugin并选择安装。WebStorm 高版本的貌似已经内置了typesCript插件,如果没有可在settings——>plugins里搜索typeScript安装。
其他编辑器省略...
简单事例
function sayHello(person: string) {
return 'Hello, ' + person;
}
let user = 'Xcat Liu';
console.log(sayHello(user));
以上代码与js不同之处在于params增加了类型的声明。编译成js时,params的类型声明就会消失。这有没有没区别啊。其实不然,在将ts编译成js的过程中,回去检查代码,如果代码不符合要求就会报错,但仍会生成js。
比如将上面的代码改为:
function sayHello(person: string) {
return 'Hello, ' + person;
}
let user = 123;
console.log(sayHello(user));
因为user是一个number类型而不是string类型,所以会报错:
typeScript数据类型
基本数据类型
boolean 和js没啥区别,值得注意的地方是使用new Boolean()创造的对象不是布尔值
string 没区别
number 没区别
null
let n: null = null
null类型的变量只能被赋值为null
undefined
let u: undefined = undefined
undefined类型的变量只能被赋值为undefined
viod
let v:viod = unll || undefined;
只能被赋值为null或者undefined,还可以用来声明函数是没有返回值的。
function alertName(): void {
alert('My name is xcatliu');
}
any
可以赋值为任意类型,在声明变量的时候如果没有指定类型则默认为any.
let myFavoriteNumber: any = 'seven';
myFavoriteNumber = 7;
值得注意的是在任意值上访问任何属性都是可以的,比如myFavoriteNumber.length
,number类型是没有length属性的,但是这时的myFavoriteNumber不是number类型而是any类型。
Union Types
联合类型,指赋值的时候可以是联合类型中的某一个。
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
但是当不确定变量是到底是哪个类型的时候,我们只能访问联合类型共有的方法。例如
function getLength(something: string | number): number {
return something.length;//若改为something.toString();就不会报错了,因为toString为共有方法
}
此时,会报错
对象类型——接口
定义对象,要用interface了,这个interface可以看做是一个抽象类,将一些行为进行抽象,而具体如何行动需要由类去实现。
一个简单的示例:
interface Person {
name: string;
age: number;
}
let xcatliu: Person = {
name: 'Xcat Liu',
age: 25,
};
定义一个变量的类型为Person时,他的属性必须遵循Perso接口的配置。接口属性配置有如下几种方式:
确定属性
上面示例代码接口属性的定义方式就是确定属性,在变量类型选择为person时就必须声明确定属性并且类型相同可选属性
interface Person {
name: string;
age?: number;
}
在属性后面增加一个?,表示此属性为可选属性,该属性是可以不存在的,在声明变量时,可省略。
let xcatliu: Person = {
name: 'Xcat Liu',
};
任意属性
允许创建对象的时候,定义接口中没有的属性。但是值得注意的一点是确定属性和可选属性都必须是任意熟悉感的子属性
interface Person {
name: string;
age?: number;
[propName: string]: any; // 属性名只能是string或number类型
}
此示例中,任意属性的类型是any,string和number都是any的子属性,所以不会报错。
只读属性
只读属性是指只有在对象创建的时候对其的赋值有效,之后对只读属性的赋值都不会生效并且会报错。
interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
只要在需要声明的只读属性前面加上readonly就可以了,这个readonly和ES6的const很像,const是在声明变量的时候用,而readonly是在声明属性的时候用。
let xcatliu: Person = {
id: 89757,
name: 'Xcat Liu',
website: 'http://xcatliu.com',
};
xcatliu.id = 9527; // 此处会报错,提示不能修改一个只读的属性
数组
let arr: number[] = [1,2,1,2];
联合类型与数组结合:
let arr: (number|string)[] = [1,2,3,'4'];
any数组:
let arr: any[] = [1,'2',{a: 'b'}];
泛型数组
泛型就是指在定义接口、函数和类的时候,先不指定具体的类型,而是在使用他的时候指定类型的一种特性。
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
在接口中使用数组:
interface NumberArray {
[index: number]: boolean;
}
let fibonacci: NumberArray = [true,false];
类数组:
例如arguments就是一个类数组类型,常见的类数组都有自己的接口定义,如 IArguments, NodeList, HTMLCollection 等
function sum() {
let args: number[] = arguments;
}
function sum() {
let args: IArguments = arguments;
}
函数
函数分为函数声明和函数表达式,两种方式如下:
// 函数声明
function add(a:number,b:number):number{
return a+b;
}
sum(1,2);
//如果没有返回值
function logSum(a:number,b:number){
console.log(a+b);
}
// 函数表达式
let sum = function(a:number,b:number):number{
return a+b;
}
sum(1,2);
/*函数表达式的声明其实只是对右侧的匿名函数进行了类型定义,
而等号右边的sum是通过**类型推论**(下面有讲到)推断出来的。也可以如下去写:*/
let sum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
//用第二种写法去书写函数表达式,可读性很差,而且感觉没有这样写的必要,不建议这样来书写。
上面用到了一个箭头函数,是es6的语法。
let sum = (a,b) => a+b;
let sum = function(a,b) {
return a+b;
}
在接口中定义函数:
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
return source.search(subString) !== -1;
}
像上面这样感觉有点多余。
函数参数:
function push(
arg1:string, // 确定参数
arg2?: string,//可选参数
lastName: string = 'Liu',//参数默认值
...items: any[]//剩余参数
) {
items.forEach(function(item) {
array.push(item);
});
}
类型推论和类型断言
类型推论
是指没有指定类型时,会依照类型推论的规则去推断出类型。
let a = 'flag';
a = 1;
比如上面的代码,没有给a指定类型,在赋值为‘flag’的时候,类推了它的类型为string,在进行a=1的赋值操作的时候,就会报错。
常见的类型推论,还提现在函数表达式中。
类型断言
是指手动去指定一个值的类型,让编译器不会因为类型问题报错。比如:
function getLength(something: string | number): number {
if (something.length) { // 此处编译时会报错,因为length属性不是string和number的共有属性
return something.length;
} else {
return something.toString().length;
}
}
改为:
function getLength(something: string | number): number {
if ((<string>something).length) { // 此时编译器将把这里的something当作string类型来处理
return (<string>something).length;
} else {
return something.toString().length;
}
}
注意: 断言只能是断言为联合类型中的类型。比如此处只能断言为string或者number.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。