TypeScript基础知识

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

基础

原始数据类型

1)布尔值: let isDone: boolean = false;

2)数值:

let decLiteral: number = 6; 

let hexLiteral: number = 0xf00d; // ES6 中的二进制表示法 

let binaryLiteral: number = 0b1010; // ES6 中的八进制表示法 

let octalLiteral: number = 0o744; 

let notANumber: number = NaN; 

let infinityNumber: number = Infinity

3)字符串:

let name:string = 'zhao'; 

let age:number = 22; //模板字符串 

let sentence: string = `Hello,my name is ${name} I'll be ${myAge + 1} years old next month.`

4)空值 JS中没有空值的概念,TS中,使用void表示没有任何返回值的函数

function alertName(): void{ 
    alert('My name is zhao'); 
}

5)Null和Undefined let u: undefined = undefined; let n: null = null

任意值

Any可以用来表示允许赋值为任意类型,如果是一个普通类型,在赋值过程中改变类型是不被允许的,但如果是any类型,则允许被赋值为任意类型。

在any上访问任何属性都是被允许的,也可以调用任何方法。可以认为,声明一个变量为任意值后,对他的任何操作,返回的内容的类型都是任意值。

变量在声明时,未指定其类型,那么它会被识别为任意值类型。

类型推理

TS会在,没有明确的指定类型时推测出一个类型,这就是类型推论。如果定义时没有赋值,不管之后有没有赋值,都会被推断为any类型而完全不被类型检查。

//以下代码虽然没有指定类型,但是会在编译的时候报错:
 

function alertName(): void{ 
    alert('My name is zhao'); 
}

//事实上,它等价于:

let myFavoriteNumber: string = 'seven'; 

myFavoriteNumber = 7; // index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

联合类型

联合类型表示取值可以为多种类型中的一种。使用 | 分隔每个类型。

let myFavoriteNumber: string | number; 

myFavoriteNumber = 'seven';

myFavoriteNumber = 7; 

let myFavoriteNumber: string | number; 

myFavoriteNumber = true; 
// Type 'boolean' is not assignable to type 'string | number'.
//Type 'boolean' is not assignable to type 'number'.

当TS不确定一个联合类型的变量到底是哪个类型的时候,会访问此联合类型的所有类型里共有的属性或方法。

function getLength(something: string | number): number { 
    return something.length; 
} 
// error TS2339: Property 'length' does not exist on type 'string | number'. 
// Property 'length' does not exist on type 'number'.

上例中,length 不是 string 和 number 的共有属性,所以会报错。

访问 string 和 number 的共有属性是没问题的:

function getString(something: string | number): string {
    return something.toString(); 
}

对象的类型——接口

在TS中,我们使用接口(Interfaces)来定义对象的类型。

接口:在面向对象中,接口(Interfaces)是对行为的抽象,具体如何行动要由类(classes)去实现(implement)。

interface Person{ name: string; age: number; } 
let zhao: Person = { name: 'zhao', age: 22 }

定义的变量比接口少了一些属性是不被允许的,多一些属性也是不被允许的。赋值时,变量的形状必须和接口的形状保持一致。

有时候我们希望不要完全匹配一个形状,可以使用可选属性

interface Person { 
    name: string; 
    age?: number; 
} 
//age可以存在也可以不存在,此时仍然不允许添加未定义的属性。

有时候我们希望一个接口允许有任意的属性,可以使用任意属性

interface Person { 
    name: string; 
    age?: number; 
    [propName: string]: any; 
} //[propName: string]定义了任意属性取string类型的值

一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集:

interface Person { 
    name: string; 
    age?: number; 
    [propName: string]: string; 
} 
let tom: Person = { 
    name: 'Tom', 
    age: 25, 
    gender: 'male' 
}; 

此时会报错,因为任意属性的值允许是string,但可选属性age的值却是number,number不是string的子属性,所以报错。

一个接口中只能定义一个任意属性,如果接口中有多个类型的属性,则可以在任意属性中使用联合类型。

interface Person { 
    name: string; 
    age?: number; 
    [propName: string]: string | number; 
} 
let tom: Person = { 
    name: 'Tom', 
    age: 25, 
    gender: 'male' 
};

只读属性

有时候我们希望对象中的一些字段只能在创建的时候被赋值,那么可以用 readonly 定义只读属性:

interface Person { 
    readonly id: number; 
    name: string; 
    age?: number; 
    [propName: string]: any; 
} 
let tom: Person = { 
    id: 89757, 
    name: 'Tom', 
    gender: 'male' 
}; 
tom.id = 9527; //报错

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

数组的类型

1)[类型+方括号]表示法: let arr:number[] = [1,2,3,4,5] 数组的项中不允许出现除number外其他的类型。

2)数组泛型:ler arr:Array<number> = [1,2,3,4,5]

3)用接口表示数组:

interface NumberArray { 

    [index: number]: number; //只要索引的类型是数字时,那么值的类型必须是数字。 
} 
let arr : NumberArray = [1,2,3,4,5]

4)类数组:

function sum() { 
    let arg: number[] = arguments; 
}

上例中,arguments 实际上是一个类数组,不能用普通的数组的方式来描述,而应该用接口:

function sum() { 
    let args: { 
        [index: number]: number; 
        length: number; 
        callee: Function; 
    } = arguments; 
}

any表示数组中允许出现任意类型:

let list:any[] = ['zhao',25,{obj:'111}];

函数的类型

函数声明

JS中:定义函数的方式有函数声明和函数表达式

TS中:一个函数有输入和输出,需要在TS中对其进行约束

1)函数声明

function sum(x:number,y:number): number{ 
    return x+y; 
} //输入多余的或少于要求的参数时不被允许的

2)函数表达式

let mySum :(x:nubmber,y:number) => number = function(x:number, y:number):number{ 
    return x+y; 
}

在TS的类型定义中,=>用来表示函数定义,左边是输入类型,需要用括号括起来,右边是输出类型。(返回类型为number)

3)用接口定义函数的形状

interface SearchFunc { (source: string, subString: string): boolean; } 
let mySearch: SearchFunc; 
mySearch = function(source: string, subString: string) { 
    return source.search(subString) !== -1; 
}

4)对于联合类型的函数,可以采用重载的方式

function getVal(value:number):number; 
function getVal(value:string):string; 
function getVal(value:string|number):string|number{ 
    return value 
} 
let a:string = getVal('zhao') //输入是string,输出也是string
let b:number = getVal(123) //输入是number,输出也是number 

类型断言

可以用来手动指定一个值的类型

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

f

unction getAssert(name:string | number){ 
    //return (<string>name).length //将name断言为string类型,jsx中不能用 
    return (name as string).string //将name断言为string类型 
}

只能转换联合类型中存在的类型

类型别名

可以给一个类型起一个新名字

type strType = string|nubmer|boolean; 
let str:strType = "10"
str = 10 
str = true

接口也可以使用类型别名

interface muchType1{ name: string } 
interface muchType2{ age:number } 
type muchType = muchType1 | muchType2 
let obj: muchType = {name:'zhao'} 
let obj1: muchType = {age:22} 
let obj2: muchType = {name:'li',age:20}

限制字符串的选择

type sex = "男"|"女" 
function getSex(s:sex):string{ 
    return s 
} 
let a = getSex("男") //男

枚举

枚举(Enum)类型用于取值被限定在一定范围内的场景。枚举成员会被赋值为从0开始递增的数字,同时也会被枚举值到枚举名进行反向映射

enum Days{ 
    Sun, Mon, Tue, Wed, Thu, Fri, Sta 
} 
console.log(Days.Sun) //0 
console.log(Days.Sat) //6 
console.log(Days[0]) //'Sun'

类修饰符

public修饰的属性或者方法是共有的,可以在任何地方被访问到,默认所有的属性或者方法都是public的

private修饰的属性或者方法是私有的,不能在声明它的类外面访问

protected修饰的属性或方法是受保护的,它和private类似

class Person{ 
    private sex="男" 
    protected marraied = false 
    name = "张" 
    age = 18 
    say(){ 
        console.log('my name is'+this.name,'my age is'+this.age) 
    } 
} 
var p = new Person() 
p.say() 
console.log(p.name) //当一个类成员变量没有修饰的时候,外界是可以进行访问的,默认public修饰 console.log(p.sex)//无法访问 
//父类protected的属性在子类里可以拿到,外面不行 
class Child extends Person{ 
    callParent(){ 
        super.say() //调父类方法 
        console.log(super.marraied)//可以访问 
    } 
    static test(){ 
        //静态方法中不可以使用this console.log('test') 
    } 
} 
var c = new Child() 
c.callParent() 
console.log(c.age) //子类继承父类,可以访问到父类公开的属性/方法 
console.log(c.sex) //无法访问 
console.log(c.marraied) //无法访问 
console.log(c.say()) 
console.log(Child.callParent()) //报错,无法直接通过类调取该方法 
console.log(Child.test()) //可以 
console.log(c.test()) //无法访问 
//总结:静态方法是属于类的

泛型

是指定义函数、接口或类的时候,不预先指定具体类型,而在使用的时候再指定类型的一种特性。

function creatArray(length:number,value:any):Array<any>{ 
    let arr = [] 
    for(let i =0;i<length;i++){ 
        arr[i] = value 
    } 
    return arr; 
} 
createArray(3,1) //[1,1,1] 
//使用泛型改造上面代码 
function creatArray<T>(length:number,value:T):Array<T>{ 
    let arr = [] 
    for(let i =0;i<length;i++){ 
        arr[i] = value 
    } 
    return arr; 
} 
let strArr:string[] = createArray<string>(3,'1')
let numArr:number[] = createArray(3,1)

接口中采用泛型

interface ICreat{ <T>(name:string,value:T):Array<T> } 
let func:ICreate; 
func = function<T>(name:string,value:T):Array<T>{ 
    return [] 
} 
let strArr:string[] = func('zhao','student') 
let strArr2:number[] = func('zhao',18)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值