对行为的抽象,具体如何行动需要由类(classes)去实现。
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
}- 上例中,赋值的时候,变量的形状必须和接口保持一致。
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom'
}- 上例中,
age可以不定义
interface Person {
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
}定义了任意属性后,确定属性和可选属性都必须是它的子属性
interface Person {
readonlu id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
id: 112358,
name: 'Tom',
gender: 'male'
}- 上例中,属性id初始化后无法被赋值。
let fibonacci: number[] = [1,1,2,3,5,8];- 数组的项中不允许出现其他类型
- 不仅在定义时会限制,使用数组方法时也会限制。如
.push
可以使用数组泛型 Array<elemType>来表示数组
let fibonacci: Array<number> = [1,1,2,3,5,8]; interface NumberArray {
[index: number]: number;
}
let fibonacci: NumberArray = [1,1,2,3,5,8];- 上例中,只要
index的类型是number,值的类型必须是number
类数组(Array-like Object)不是数组类型,比如 arguments
function sum() {
let args: number[] = arguments;
}- 常见的类数组都有自己的接口定义,如
IArguments,NodeList,HTMLCollection等
function sum() {
let args: IArguments = arguments;
}1.函数声明
function sum(x :number, y: number): number {
return x + y;
}- 只能输入相应的参数,不能多也不能少
2.函数表达式
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;
}TypeScript 中的=>和 ES6 中的=>是不同的
在TypeScript的类型定义中,=>用来表示函数的定义,左边是输入类型,需要用括号扩起来,右边是输出类型。
在ES6中,=>是箭头函数。
3.接口定义
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(src: string, sub: string){
return src.search(sub) !== -1;
} function buildName(firstName: string, lastName?: string) {
if(lastName) {
return firstName + ' ' + lastName;
} else {
return firstName;
}
}可选参数必须在最后定义
function buildName(firstName: string, lastName: string = 'Cat'){
return firstName + ' ' + lastName;
} function push(array, ...rest) {
rest.forEach(function(item){
array.push(item);
})
}rest是一个数组,我们可以用数组来定义
function push(array: any[], ...rest: Array<any>){
rest.forEach(function(item){
array.push(item);
});
}rest参数只能是最后一个参数
重载允许一个函数接收不同数量或类型的参数时,做出不同的处理。
例:反转函数
function reverse(x: number): number;
function reverse(x: string): string;
// 多次定义函数 reverse,精确表达 输入为数字时,输出也为数字;输入为字符串时,输出也为字符串。
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('');
}
}优先把精确的定义写在前面
手动指定一个值的类型。
<类型>值 或者 值 as 类型
- 在tsx中必须用后一种
function getLength(something: string | number): number {
if((something as string).length) {
return (something as string).length;
}else{
return something.toString().length;
}
}使用第三方库时,需要引用它的声明文件
使用第三方库jQuery
declare var $: (string) => any;
$('#foo');通常把类型声明放到一个单独的文件中
// jQuery.d.ts
declare var $: (string) => any;- 文件名以
.d.ts为后缀
在使用到的文件开头,用 /// 表示引用了声明文件
/// <reference path='./jQuery.d.ts' />
$('#foo');推荐使用工具统一管理第三方库的声明文件。如 @types;
@types 安装jQuery声明文件
npm install @types/jquery --save-dev
在这个页面搜索需要的声明文件
JavaScript中的内置对象可以直接在TypeScript中当做定义好了的类型
如Boolean、Error、Date、RegExp
let b: Boolean = new Boolean(1);
let e: Error = new Error('Error occurred');
let d: Date = new Date();
let r: RegExp = /[a-z]/;如Document、HTMLElement、Event、NodeList
let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelector('div');
document.addEventListener('click', function(e:MouseEvent) {
})以上两种内置对象的定义文件都在TypeScript核心库的定义文件中
TypeScript核心库的定义文件中定义了所有浏览器环境需要用到的类型,并且是预置在TypeScript中的。当使用一些常用的方法的时候,TypeScript实际上已经做了很多类型判断的工作
Math.pow(10,'2');
// 该方法会报错,因为只能接受两个number类型的参数实际上,Math.pow的类型定义如下
interface Math{
pow(x: number, y: number): number;
}DOM中的例子
document.addEventListener('click', function(e) {
console.log(e.targetCurrent);
});
// 该方法会报错,因为MouseEvent没有targetCurrent属性类型定义
interface Document extends Node, GlobalEventHandlers, NodeSelector, DocumentEvent {
addEventListener(type: string, listenerL (ev: MouseEvent) => any, useCapture?: boolean): void;
}需要引入第三方声明文件
npm install @types/node --save-dev