TypeScript-1

一、基础

1. 原始数据类型:boolean,number,string,undefined,null,Symbol

let isDone:boolean=true;
let num:number=6;
let str:string='asd';
let u:undefined=undefined;
let n:null=null;
// 空值 ,用void表示没有任何返回值的函数
function test():void{
   alert('122');
}
// void 类型的变量只能赋值为 undefined 和 null
let unusable:void=undefined;

// undefined,null是所有类型的子类型,可以赋值给其他类型的变量
num=null;
console.log(num);//null

2.任意值

任意值用来表示允许赋值为任意类型

//1. any类型,允许被赋值为任意类型,
let num:any=7;
num='123';

// 2.声明一个变量为任意值之后,对它的任何操作,返回的内容的类型都是任意值。

let obj:any={};
obj.name='11'
console.log(obj.name);

// 3.变量如果在声明的时候,未指定其类型,会被识别为任意值类型
let a;
a='bbb';
a=1111;//success

let str='aaa';
str=123;//error 类型错误

 

3. 类型推论

   如果没有明确的指定类型,TypeScript 会依照类型推论(Type Inference)的规则推断出一个类型。

let str='aaaaa';//等价于 let str:string='aaaaa';
str=123;//error

// 如果定义的时候没有赋值,不管之后有没有赋值,都会被推断成 any 类型而完全不被类型检查:
let num;
num='aaa';
num=111;//success

 4.联合类型

取值可以为多种类型的一种
// 1.联合类型的变量在被赋值的时候,会根据类型推论的规则推断出一个类型:
let str:string|number;
str='abc';
console.log(str.length);//3
str=123;
console.log(str.length);//error: Property 'length' does not exist on type 'number'

//2. 只能访问此联合类型的所有类型里共有的属性或方法:
function test(params:string|number):string{
    return params.toString();
}

 

 5.对象的类型--接口

使用接口来定义对象的类型

接口:可用于对类的一部分行为进行抽象,也用对 对象的形状进行描述

 

//1.接口一般首字母大写,赋值的时候,变量的形状必须和接口的形状保持一致
interface Person{
    name:string;
    age:number;
}
let test:Person={
    name:'sy',
    age:12
}
// 2.可选属性 ?:属性可以不存在,但是不允许添加未定义的属性
interface Person{
    name:string;
    age?:number;
}
let test:Person={
    name:'123',
    color:'red'//error ... 'color' does not exist in type 'Person'.
}

// 3.任意属性
interface Person{
    name:string;
    age?:number;
    [propName:string]:any;

}
let test:Person={
    name:'sy',
    color:'red'
}
// // 一旦定义了任意属性,那么确定属性和可选属性都必须是它的子属性:
interface Person1{
    name:string;
    age?:number;
    [propName:string]:string;//error:任意属性的值允许是 string,但是可选属性 age 的值却是 number,number 不是 string 的子属性,所以报错了

}

// 4.只读属性:readonly

interface Person{
    readonly id:number;
    name:string;
    age?:number;
    [prop:string]:any;
}
let test:Person={
    id:123,
    name:'sy',
    sex:'woman'
}
test.id=11;//error:Cannot assign to 'id' because it is a constant or a read-only property.

// 只读的约束存在于第一次给对象赋值的时候,而不是第一次给只读属性赋值的时候

let person:Person={
    name:'aa',// error:Property 'id' is missing in type '{ name: string }'
}
person.id=11;//error:Cannot assign to 'id' because it is a constant or a read-only property.

 6.数组的类型

//1. 使用「类型 + 方括号」来表示数组

let arr:number[]=[1,2,3];

// 数组中不允许出现其他类型
let arr1:number[]=[1,2,3,'a'];//error: Type 'string' is not assignable to type 'number'.

let arr2:(number|string)[]=[1,2,3,'a'];//联合类型

// 2.使用数组泛型 Array<elemType> 来表示数组:

let arr:Array<number>=[1,2,3];

// 3.用接口表示数组

interface NumberArray{
    [index:number]:number;
}
let arr1:NumberArray=[1,2,3];

// 4.any 表示数组中允许出现任意类型
let list:any=[1,'asas',{name:'sy'}];

// 5.类数组

// 常见的类数组都有自己的接口定义,如 IArguments, NodeList, HTMLCollection 等:
function sum(){
    let args:IArguments=arguments;
    let arr:number[]=arguments;//error:Property 'push' is missing in type 'IArguments'.
}

 

 7.函数的类型

 
// 1.函数声明

// 参数必须相同
function sum(x:number,y:number):number{
    return x+y;
}
sum(1,2);
sum(1,2,3);//error: Expected 2 arguments, but got 3.

// 2.函数表达式

// 在 TypeScript 的类型定义中,=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
let sum:(x:number,y:number)=>number=function(x:number,y:number):number{
    return x+y;
}

// 3.用接口来定义函数的形状
interface PersonFun{
    (name:string,age:number):boolean
}

let test:PersonFun;
test=function(name:string,age:number):boolean{
    return age>10;
}

// 4.可选参数?
// 可选参数必须接在必需参数后面
function sum( x:number,y?:number):boolean{
    return y?true:false;
}
sum(1,2);//true
sum(1);//false

// 5.参数默认值

function test(name:string,age:number=10){
    return name+age;
}
test('sy');//"sy10"

// 6.剩余参数: ...rest 的方式获取函数中的剩余参数

function push(arr,...items){
    items.forEach((item)=>{
        arr.push(item);
    })
}
let arr=[];
push(arr,1,3,4,5);// [1, 3, 4, 5]

// 7.重载:重载允许一个函数接受不同数量或类型的参数时,作出不同的处理。

// TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面

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('');
    }
}
let a=reverse(123);//321
let b=reverse('hello');//"olleh"

 

8.类型断言

类型断言(Type Assertion)可以用来手动指定一个值的类型。

// 语法:<类型>值 或  值 as 类型

function getLength(param:string|number){
    if((<string>param).length){
        return (<string>param).length
    }else{
        return param.toString().length;
    }
}


// 类型断言不是类型转换,断言成一个联合类型中不存在的类型是不允许的

function toBoolean(param:string|number):boolean{
    return <boolean> param;//error: Type 'string | number' cannot be converted to type 'boolean'
}

 

9.声明文件

 当使用第三方库时,我们需要引用它的声明文件。

// 1.声明语句
// 使用 declare 关键字来定义它的类型,

declare var jQuery: (selector: string) => any;

jQuery('#foo');

// 2.声明文件
// 通常我们会把类型声明放到一个单独的文件中,这就是声明文件:

// jQuery.d.ts
declare var jQuery: (string) => any;

// 然后在使用到的文件的开头,用「三斜线指令」表示引用了声明文件:

/// <reference path="./jQuery.d.ts" />
jQuery('#foo');

// 3.第三方声明文件
// TypeScript 2.0 推荐使用 @types 来管理。

// @types 的使用方式很简单,直接用 npm 安装对应的声明模块即可,以 jQuery 举例:
npm install @types/jquery --save-dev

 

10.内置对象

内置对象是指根据标准在全局作用域上存在的对象。 里的标准是指 ECMAScript 和其他环境(比如 DOM)的标准。

 
// 1.ECMAScript 的内置对象
// 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]/;


// 2.DOM 和 BOM 的内置对象
// Document、HTMLElement、Event、NodeList 等。

let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent) {
  // Do something
});

// 3.TypeScript 核心库的定义文件

// 定义了所有浏览器环境需要用到的类型,并且是预置在 TypeScript 中的

// 4.用 TypeScript 写 Node.js
// Node.js 不是内置对象的一部分,如果想用 TypeScript 写 Node.js,则需要引入第三方声明文件:

npm install @types/node --save-dev

 

 
posted @ 2018-11-15 17:39  yuesu  阅读(142)  评论(0编辑  收藏  举报