初步了解 TypeScript

准备

为何要用 typescript

  • 我们在定义一个函数,仅仅只是操作字符串, 但是人总会疏忽,在 js 中传递进去的对象,函数也一样能运行
  • 由此,我们需要一个在运行前帮我们检测,并约束数据类型的语法
  • Angular里面
    • 1.x更名为 AngularJS
    • 2.x 以上都称之为 AngularlO

起步

  • 安装编译 TypeScript语法到 js 语法的编译工具
npm install -g typesctipt
  • 编写代码
function greeter(person: string){
    return 'Hello,'+ person
}
let user = 'zm'
document.body.innerHTML = greeter(user)
  • 编译代码
tsc index.ts

常见错误处理

tsconfig.json

tsconfig.json 是 TypeScript 的编译选项文件,通过配置它来定制 TypeScript 的编译细节。

  • 直接调用 tsc,编译器会从当前目录开始去查找 tsconfig.json 文件,逐级向上搜索父目录。
  • 调用 tsc -p,可以指定一个包含 tsconfig.json文件的目录进行编译。如果没有找到 tsconfig.json 文件,TypeScript 会编译每个文件并在对应文件的同级目录产出。

一个 tsconfig.json 文件描述:

{
  // 编译选项
  "compilerOptions": {
    // 输出目录
    "outDir": "./output",
    // 是否包含可以用于 debug 的 sourceMap
    "sourceMap": true,
    // 以严格模式解析
    "strict": true,
    // 采用的模块系统
    "module": "esnext",
    // 如何处理模块
    "moduleResolution": "node",
    // 编译输出目标 ES 版本
    "target": "es5",
    // 允许从没有设置默认导出的模块中默认导入
    "allowSyntheticDefaultImports": true,
    // 将每个文件作为单独的模块
    "isolatedModules": false,
    // 启用装饰器
    "experimentalDecorators": true,
    // 启用设计类型元数据(用于反射)
    "emitDecoratorMetadata": true,
    // 在表达式和声明上有隐含的any类型时报错
    "noImplicitAny": false,
    // 不是函数的所有返回路径都有返回值时报错。
    "noImplicitReturns": true,
    // 从 tslib 导入外部帮助库: 比如__extends,__rest等
    "importHelpers": true,
    // 编译过程中打印文件名
    "listFiles": true,
    // 移除注释
    "removeComments": true,
    "suppressImplicitAnyIndexErrors": true,
    // 允许编译javascript文件
    "allowJs": true,
    // 解析非相对模块名的基准目录
    "baseUrl": "./",
    // 指定特殊模块的路径
    "paths": {
      "jquery": [
        "node_modules/jquery/dist/jquery"
      ]
    },
    // typescript 编译过程中需要引入的库
    "lib": [
      "es2015",
      "es2015.promise"
    ]
  }
}

类型

布尔值
let isDone: boolean = false
数字
let num: number = 1111
字符串
let name: string = 'zj'
数组
let list: number[] = [1, 2, 3]
任意类型数组
let arr: any[] = [1, '2', 3, true, {name: 'zj'}]
枚举(更友好的名称,相当于键值对)
enum Color {red, green, blue}
let c: Color = Color.red; // 0 方式一 看做一个对象,key 可以是双向的,既可以通过索引取名称,也可以通过属性名获取
let msg: string = Color[1] // green 方式二 看做一个数组 
Viod
  • 一般作为函数没有返回值的表示,而不作为变量类型的声明
  • 因为它没有任何类型
function test(): viod {
    console.log('Hello Word')
}
Null 和 Undefined
类型断言
  • 可以理解为 强制类型声明

类型断言有两种形式。一种是 “尖括号” 语法:

let value: any = "this is a string"
let str: string = <string>value

另一个为 as语法:

let value: any = "this is a string"
let str: string = value as string

基本使用(里面不要放 let / const )

class Greeter{
    greeting: string;
    constructor(message: string){
        this.greeting = message;
    }
    greet(){
        return "Hello, "+ this._greeting;
    }
}
let greeter = new Greeter('word');

继承语句

class student extends Person{}
new Student();

公共,私有与受保护的修饰符

公共(默认和不写一样)
  • public 代表可以在 class{} 以外的地方访问
class Person {
    public name: string = 'abc';
    private age: number = 50;
    protected money: number = 10000;
}
class Son extends Person {
	getParentAge(){
        this.age // 报错, 受保护的无法访问
    }
    getParentMoney(){
        this.money // 10000
    }
}
let p = new Person();
p.name // 可以访问
p.money // 无法访问
p.age // 无法访问
readonly 只读修饰符
  • 类似于之前使用的 const,只能被赋值一次,不能在被赋值
class Person {
    public readonly name: string = 'zj'
}
let p = new Person();
p.name = '1111' // Error
静态属性(static)
  • 使用类名 . 属性名 访问
  • 类似构造函数的的属性 function P(){}; P.age = 123
  • 静态属性不是实例的属性 function P(){};P.prototype.age = 10
  • 组合写法
class Xxx{
    public static readonly name: string = 'zh'
}
Xxx.name

get/set 存储器

error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
因为默认使用的是 ES3 的代码规范编译的,可以提高 ES5 的代码规范版本

tsc -t ES5 .\08.getter_setter.ts
  • 可以运行
class Person {
    private _age: number = 13;
    public get age(): number {
        return this._age
    }
    public set age(v: number){
        this._age = v
    }
}
let p = new Person()
p.age = 100;
console.log(p.age)
  • 小结:
    • public/readonly这类修饰符是在编译期间对代码的约束,而不能管到编译结束后的约束
    • 静态不能访问实例,但是实例可以访问静态(历史不能学人,但是人可以学历史)

抽象类

  • 每个 class的属性定义都很随意。可以通过抽象类来管理其必备那些属性及方法
  • 抽象类中可以有抽象方法(给子类实现),也可以有已实现的方法
abstract class Animal {
    abstract makeSound(): void;
    move(): void{
        console.log('动物们正在移动...')
    }
   
}
  • 第二行:子类必须实现,或者子类也是抽象类并声明该方法为抽象方法

接口(约定、规范)

  • 偏向于规则定义
  • 只定义,不实现的抽象类
  • 接口可以用来实现,而不是继承,所以对应类必须实现接口的方法和属性
额外属性检测
  • 有时候我们在应用接口的时候,可能会额外的添加一些属性或方法,这时候就需要额外类型检测
interface Person {
   readonly name: string;
   readonly age: number;

   [propName: string]: any; // 添加这一行代码
}
函数类型
interface SearchFunc {
   (source: string, subString: string): boolean
}
let mySearch: SearchFunc = (src, sub) =>{ // 可以省略类型声明
   let result = src.search(sub)
   return result > -1
}
  • 有一个参数列表 (source: string, subString: string)
    • 参数列表中必须有 name: type
  • 还有 返回值boolean(类型的函数定义)
  • 调用方法还是一样的
    • 在调用中 形参类型必须与接口中的参数列表保持一致
    • 形参可以不用声明类型,方法也可以不声明类型,typescript会自动检测是否与接口一致
数组类型
interface ArrayType {
	[index: number]: string;  // 声明数组成员
}

let arr: ArrayType;
arr = ['Dog', 'Cat'];
类实现接口
  • 一个类只能继承一个类(单继承),一个类可以实现多个接口,都是定义规则
// 定义一个 动物的基本信息接口
interface Animal {
   kind: string; // 种类
   // 介绍动物
   detail(kind: string, sex: string): string
}

class Dog implements Animal{
   kind = '11'
   detail(kind: string, sex: string): string{
      return kind + sex
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值