TypeScript

  • TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准(ES6 教程
  • TypeScript 由微软开发的自由和开源的编程语言。
  • TypeScript 设计目标是开发大型应用,它可以编译成纯 JavaScript,编译出来的 JavaScript 可以运行在任何浏览器上。
JavaScript 与 TypeScript 的区别:
  • TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。
  • TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。
1、TypeScript作用域问题
// 如果我们在一个ts文件中添加了一个全局变量,那么在其他ts文件中就不能再去声明这个变量了

// 例:
1.ts
const a = 123

2.ts
const a = '123'
// 2.ts文件中就会报出,a已经声明过了,不能再声明
// 解决办法:
// 我们可以把2.ts作为一个模块导出,export {},因为模块是有单独作用域的,所以和1.ts文件不会产生冲突
2、Object类型
  • object类型并不是单只对象类型,而是泛指所有的非原始类型。也就是对象、数组、函数
// 例:
const foo: object = // 可是是函数 function() {}、数组[]、对象{}

// 如果要单独定义对象的话,可以使用
const foo: {} = {}

// 如果要单独针对对象里面的字段进行定义的话,可以使用
const foo: {name: string, age: number} = { name: 'jack', age: 23 }
// 注意:定义的对象必须要跟我们定义的变量的解构完全一致,否则会报错
3、数组类型
const foo: Array<number> = [1,2,3] // 表示定义一个数组中只能是数字的变量,其他会报错
// 或
const foo: number[] = [1,2,3]

// 例子:计算一个数组的和,但是传的值必须是数字
function sum(...args: number[]) { // 代表必须全部是由数字组成的数组类型
  return args.reduce((prev, current) => {
    return prev + current
  }, 0)
}
console.log(sum(1,2,3,4,5)) // 15
4、元组类型
  • 明确元素数量以及每个元素类型的一个数组
// 例子:
const arr: [name: string, age: number] = [name: 'jack', age: 23]
// 这种就是元组类型
5、枚举类型
enum upOrDown {
    down = 0,
  up = 1
}
// 定义枚举
// 或
enum upOrDown {
    down,
  up
}
// 默认从0开始网上递增
// 如果定义的值不是数字,那就必须的写上对应的值

const goods = {
    name: '天猫精灵',
  price: 99,
  index: upOrDown.down // 0 未上架、1 已上架
}
// 通过upOrDown.dowm / upOrDown.up拿到对应的类型

// 注意:枚举类型会影响到我们编译后的结果

// 上面代码编译后对应的js文件会变成如下
var upOrDown;
(function (upOrDown) {
    upOrDown[upOrDown["down"] = 0] = "down";
    upOrDown[upOrDown["up"] = 1] = "up";
})(upOrDown || (upOrDown = {}));
const goods = {
    name: '天猫精灵',
    price: 99,
    index: upOrDown.down // 0 未上架、1 已上架
};
// 如果不想这样做的话我们可以定义 const
const enum upOrDown {
    down,
  up
}
// 编译后:
const goods = {
    name: '天猫精灵',
    price: 99,
    index: 0 /* down */ // 0 未上架、1 已上架
};
6、函数类型
  • 函数定义的方式有两种:函数声明、函数表达式
// 1、函数声明
function foo(name: string, age: number): string {
    return `my name is ${name}, age ${age}`
}
foo('jack', 23)
/**
 * 1、foo函数我们定义了两个参数,那么我调用foo方法的时候也必须传两个参数,不能多也不能少
 * 2、并且这两个参数我们分别定义了name必须为字符串类型,age必须为数字类型。如果我们传入的
 * 是其他类型也会报错
 * 3、我们还定义了返回值必须为string类型,如果返回的是其他类型也会报错
 * 4、如果我们定义可选参数可以在参数名后面加上'?',例子:age?: number。注意:可选参数必须定义在参数 * 的最后
 */

// 2、函数表达式
const foo = function(name: string, age: number): string {
    return `my name is ${name}, age ${age}`
}
foo('jack', 23)
/*
*   1、接受函数的这个变量也是有类型的,比如我们现这个函数返回的是一个字符串,那么这个foo变量应该就是
*   string类型
* 2、如果我们在编辑器中写上函数的话,会提示const foo: (name: string, age: number) => string
*/
7、任意类型(any)
  • any是动态类型可以接受任意的值,不会报任何语法上的错误,any是不安全的,所以不要轻易的去使用
function foo (value: any) {
    console.log(value)
}
foo(12)
foo('string')
foo(true)
// 以上定义的any类型所有值都可以接受
8、隐式类型推断
  • 隐式类型推断就是你在定义一个变量或者其他的时候,如果你没有给它定义类型,它会根据你的代码或者值推断出其类型
let age = 18
/**
 * 比如你定义一个age = 18的变量,在编辑器中你会看到这样一个注解:let age: number
 * 意思就是定义了一个变量age,类型是number类型
 */

// 如果你将这个变量重新赋值,例:
age = '123'
// 这样的话编辑器中就会报:let age: number,不能将类型“string”分配给类型“number”。

建议:给每个变量添加明确的类型,这样便于后期理解我们的代码

9、类型断言(as)
  • 类型断言的意思就是说:使用者非常确定我们定义的值是什么类型,但是代码并不确定。这个时候我们就可以使用断言的方式告诉代码,我们定义的是什么类型
const list = [1, 2, 3, 4, 5] // 定义一个变量全是数字的数组
const res = list.find(i => i > 0) // 获取数组中第一个大于0的数字,返回的肯定是一个数字
const result = res * res // 这个时候代码中会提示:const res: number | undefined,意思就是说res是个数字也有可能是 undefined,所以我们就不能是 * 来进行计算

解决方法:使用断言的方式
const num = res as number // 断言res一定是一个number类型
const result = res * res // 这样计算就不会出现代码报错的问题
10、接口(interface)
  • 接口就是用来约束一个对象的结构,一个对象去实现一个接口,那它就必须去拥有这个接口当中的所有成员,以及对应成员的类型
function foo (person) {
  console.log(person.name)
  console.log(person.age)
}
// 这个时候person就会报:(parameter) person: any

// 这个时候我们可以给这个参数定义一个接口
interface Person {
  name: string
  age: number
}
function foo (person: Person) {
  console.log(person.name)
  console.log(person.age)
}

foo({
  name: 'jack',
  age: 23
})
/*
* 我们在调用这个方法的时候,就必须得传一个对象,这个对象就必须得包含name和age
* 并且name是string类型,age是number类型,否则会报语法错误
*/

// 接口中还可以定义:可选成员、只读成员、动态成员
// 可选成员:就是说我们定义的接口中字段可以有也可以是undefined,例:
interface Person {
  name: string
  age: number
  work?: string // 我们可以在work后面加一个 ? 来体现出我们这个字段是可选值
}

// 只读成员:就是说我们定义的字段是不能修改的
interface Person {
  name: string
  age: number
  work?: string
  readonly sex: string // 这个就是我们定义的成员只能读取,不能修改
}
  
// 动态成员:在我们不确定的情况我们可以定义动态成员
interface Person {
  [key: string]: string // key就是我们定义的键,类型为string,后面的string是值的类型
}
const person: Person = {
    
}
这样我们就可以随意的想person对象中添加值
person.name = 'jack'
person.sex = '男'
11、类
  • 类就是一个具体事物的抽象特征,TypeScript中的类其实和js中的类差不多
// 1、基本使用
class Person {
  name: string
  age: number
  // 以上是和js的区别,我们如果要在构造函数中是this的话,必须在上面定义一个对应的值
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  sayHi(msg: string): void {
    console.log(`I am ${this.name}`)
  }
}

// 类的访问修饰符
1、private(私有属性)
class Person {
  name: string
  private age: number // 如果我们在age上面定义了一个private私有属性的话,那这个age只能在类的内部去访问
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  sayHi(msg: string): void {
    console.log(`this is ${this.name}`)
        console.log(`this is ${this.age}`) // 可以访问到age属性
  }
}
const jack = new Person('name', 18)
console.log(jack.name) // 可以访问到name属性
console.log(jack.age) // 访问不到age属性

2、public(公有属性)
class Person {
  public name: string // 不加public默认就是public,建议添加,这样便于后期代码的可读性
  private age: number // 如果我们在age上面定义了一个private私有属性的话,那这个age只能在类的内部去访问
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
  sayHi(msg: string): void {
    console.log(`this is ${this.name}`)
        console.log(`this is ${this.age}`) // 可以访问到age属性
  }
}
const jack = new Person('name', 18)
console.log(jack.name) // 可以访问到name属性
console.log(jack.age) // 访问不到age属性

2、protected(受保护的)
// 只能在子类中访问到,外部也是访问不到的,这是和private的区别
class Person {
  public name: string // 不加public默认就是public,建议添加,这样便于后期代码的可读性
  private age: number // 如果我们在age上面定义了一个private私有属性的话,那这个age只能在类的内部去访问
    protected gender: true
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
        this.gender = true
  }
  sayHi(msg: string): void {
    console.log(`this is ${this.name}`)
        console.log(`this is ${this.age}`) // 可以访问到age属性
        console.log(`this is ${this.gender}`) // 可以访问到gender属性
  }
}
class Student extends Person {
  constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender) // 能访问到gender属性
  }
}

const jack = new Person('name', 18)
console.log(jack.name) // 可以访问到name属性
console.log(jack.age) // 访问不到age属性
console.log(jack.gender) // 访问不到gender属性

注意:如果在构造函数上使用private方法,那这个类型就不能在外部被实例化
class Student extends Person {
  private constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender)
  }
}

const tom = new Student() // 无法实例化

解决方法:
class Student extends Person {
  private constructor(name: string, age: number) {
    super(name, age)
    console.log(this.gender)
  }
    // 添加静态方式去返回这个实例对象
  static create (name: string, age: number) {
    return new Student(name, age)
  }
}

const tom = Student.create('tom', 18) // 这样就可以create静态方法去创建实例对象了

未完待续......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容