TypeScript 是一种由微软开发的开源编程语言,它是 JavaScript 的超集,提供了静态类型检查、面向对象编程、泛型等高级特性,可以使 JavaScript 代码更加可读、可维护和可扩展。随着 TypeScript 在前端开发中的广泛应用,学习 TypeScript 已经成为了前端开发者必不可少的技能之一。
使用tsc命令,并且指定编译文件时,不会使用tsconfig.json文件进行编译
shelltsc idnex.ts
使用tsc命令,并且不添加任何参数时,会使用tsconfig.json文件进行编译
tsc
tslet str:string='bob'
ts// 普通数字类型(默认十进制)
let decLiteral: number = 20
// 主动设置进制
let hexLiteral: number = 0x14 //(16进制)
let binaryLiteral: number = 0b10100 //(2进制)
let octalLiteral: number = 0o24 //(8进制)
ts// 主动申明类型,申明isDone为boolean类型,后续isDone只能为boolean类型
let isDone: boolean = false
// Ts默认指定初次类型,ts会默认为boolean类型,后续isDone只能为boolean类型
let isDone = false
通常我们用于函数。当一个函数没有返回值时,你通常会见到其返回值类型是 void
声明一个 void 类型的变量没有什么大用,因为你只能为它赋予 undefined 和 null(因为 undefined 和 null是所有类型的子类型)
tsfunction warnUser():void{
console.log('This is my waring message')
}
默认情况下 null 和 undefined 是其他任意类型的子类型(除了never), 就是说你可以把 null 和 undefined 赋值给其他类型的变量。
null和undefined使用
tslet u: undefined = undefined
let n: null = null
可以赋值给其他类型
tslet str:string='boo'
str=null
严格检查 如果开启严格检查,将无法任意赋值给其他类型,只能赋值给void类型(undefined)
tslet str:void = null //无法生效
let str:void = undefined //可以生效
也许在某处你想传入一个 string 或 null 或 undefined,你可以使用联合类型 string | null | undefined
never 类型表示的是那些永不存在的值的类型。never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never 类型,当它们被永不为真的类型保护所约束时。 never 是其它类型(包括 null 和 undefined)的子类型
tsfunction error(message:string):never{
throw new Error(message)
}
function loop():never {
while(true){ }
}
any跳过类型检查,可以为任何值,但是无法赋值给never
tslet notSure: any = 4
notSure = 'maybe a string instead'
notSure = false
let list:any []=[1,'2',true]
let list1:Array<any>=[1,'2',true]
申明全为数字的数组
ts// 第一种,可以在元素类型后面接上
let list:number []=[1,2,3,4,5]
// 第二种方式是使用数组泛型,Array<元素类型>
let list:Array<number>=[1,2,3,4,5]
数组类型错误示范
let list:[]=[1,2,3,4,5] // Error let list:Array=[1,2,3,4,5] // Error
多维数组使用
tsfunction f(arr:number [][]){ // 定义类型的时候,二维数组时为[][]
}
f([[1,2,3],[4,5,6]])
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
tslet x:[number,string]=[1,'hello']
let x:[number,string]=[1,'hello',1] // Error 超过已定义的元素数量,会报错
当访问一个已知索引的元素,会得到正确的类型
console.log(x[0].substr(1)) // Error console.log(x[1].substr(1))
ts// 第一种定义方式
declare function create(o:object|null):void
create({prop:0})
// 第二种定义方式
let obj:object|null={}
obj=null
enum 类型是对 JavaScript 标准数据类型的一个补充
key值必须是字母开头,value必须是数字
默认情况下,从 0 开始为元素编号
tsenum Color {Red, Green, Blue}
let c= Color.Red
console.log(c) //0
提供反查功能
tsenum Color {Red, Green, Blue}
let c= Color.Red
let d=Color[0]
console.log(c,d) //0,'Red'
有时候你会遇到这样的情况,你会比 TypeScript 更了解某个值的详细信息。 通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。
尖括号”语法方式
tslet someValue: any = 'this is a string'
let strLength: number = (<string>someValue).length
as 语法
tslet someValue: any = 'this is a string'
let strLength: number = (someValue as string).length
string number boolean null any void => undefined => never array object void
tslet a:any='1'
let n:number=1
n=a
n='2' // err
n=2 // ok
tsinterface SquareConfig {
color?: string,
width?: number,
height:number
}
color和width为可选属性,非必填项。 height为必填属性。
tsinterface Point {
readonly x:number,
readonly y:number
}
let p1:Point={x:10, y:20}
p1.x=30 // Error
问题:使用到接口未定义的值时,会报错。
方案一:类型断言
tslet mySquare=createSquare({colour:'123'} as SquareConfig)
方案二:字符串索引联合签名
tsinterface SquareConfig {
color?: string,
width?: number,
[propName:string]:any
}
方案三:将这个对象赋值给一个另一个变量(不推荐,逃避检查)
tslet options={colour:'123'}
let mySquare=createSquare(options )
tsinterface SearchFunc {
(source:string,subString:string):boolean
}
let mySearch:SearchFunc=function(src,sub){
let result=src.search(sub)
return result>-1
}
申明当用数字索引时,返回的值只能是string类型
tsinterface StringArray {
[index: number]: string
}
let myArray: StringArray
myArray = ['Bob', 'Fred']
let myStr: string = myArray[0]
tsinterface Counter {
(start: number): string
interval: number
reset(): void
}
function getCounter(): Counter {
let counter = (function (start: number) { }) as Counter //将couter断言为Counter
counter.interval = 123
counter.reset = function () { }
return counter
}
let c = getCounter()
c(10)
c.reset()
c.interval = 5.0
当一个类实现了一个接口时,只对其实例部分进行类型检查。
constructor 存在于类的静态部分,所以不在检查的范围内。
不会对函数参数部分进行检查,但是会对返回值进行检查(void行为怪异)
接口设置的参数不会被默认继承到类的参数里面
例子1:类里的函数参数没有被类型检查
tsinterface Clock {
a(x:string,y:string):void
}
class C implements Clock{
a(x,y){
return 10
}
}
let c=new C()
c.a('1',33) // 成功 y值为string,但是设置为数字类型也通过了,说明类的参数里面没有类型要求
例子2:类里的函数参数需手动设置类型检查
tsinterface Clock {
a(x:string,y:string):void
}
class C implements Clock{
a(x:string,y:string){ // 类型改成number,会报错,需要和接口里面申明的一致
return 10
}
let c=new C()
c.a('1','12') // 正确,参数改成数字会报错
返回值设置为string,number等这些类型,会被检查,设置为void不会被检查
例子1:string返回值检查
tsinterface Clock {
a():string
}
class C implements Clock{
a(){
return 1 // 错误,改成'1'即可
}
}
例子2:void返回值不检查
tsinterface Clock {
a():void
}
class C implements Clock{
a(){
return 1 // 正确,改成‘1’也可以,改成任意值都可以。怀疑设置成void的时,不会进行返回值检查
}
}
tsinterface Interface {
new(hour: number, minute: number)
}
class DigitalClock {
constructor(hour,minute) {
}
}
let A:Interface=DigitalClock
let b=new A(1,2)
tsinterface Shape {
color:string
}
interface PenStroke {
penWidth:number
}
interface Square extends Shape,PenStroke{
sideLength:number
}
let square={} as Square //接口断言时,如s as Square,s必须包含Square,但是{ } 不用
square.color='blue'
square.penWidth=5.0
square.sideLength=10
当接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的 private 和 protected 成员。 这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)。 实际发现会继承类的成员包括实现
tsclass Control {
private state: any
}
interface SelectableControl extends Control {
select(): void
}
// 说明:SelectableControl 会继承私有属性private state: any
class ImageC implements SelectableControl { // Error:“ImageC”类型缺少“state”属性。
select() { }
}
class Button extends Control implements SelectableControl { //先继承Control 私有属性
select() { }
}
tstype Easing = 'ease-in' | 'ease-out' | 'ease-in-out'
let a:Easing='ease-in' // OK
let b:Easing='ease' // ERR
ts会自己根据类型进行推断
ts// 第一种
let myAdd:(x:number,y:number)=>number=function(x,y){
return x+y
}
// 第二种
let myAdd=(x:number,y:number):number=>{
return x+y
}
tsinterface Deck {
name:string,
getName(this:Deck):()=>String
}
let deck:Deck={
name:'str',
getName:function (this:Deck) {
return ()=>{
return this.name
}
}
}
let f1=deck.getName()
console.log(f1())
tsfunction pickCard(x:number,b:string):number
function pickCard(x:string,b:number):string
function pickCard(x,y):any{
return x
}
console.log(pickCard('1',2))
typeof类型保护
tslet a:string|number
if(typeof a==='string'){
console.log(a.length) // OK
console.log(a.toFixed()) // ERR
}
if(typeof a==='number'){
console.log(a.length) // OK
console.log(a.toFixed()) // ERR
}
instanceof 类型保护
tsclass Bird {
fly () {
console.log('bird fly')
}
}
class Fish {
swim () {
console.log('fish swim')
}
}
function getRandomPet () {
return Math.random() > 0.5 ? new Bird() : new Fish()
}
let pet = getRandomPet()
if (pet instanceof Bird) {
pet.fly()
}
if (pet instanceof Fish) {
pet.swim()
}
本文作者:BARM
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!