TypeScript入门指北(一)

·  阅读 115

TypeScript

安装

npm install -g typescript

tsc -v 

Version 4.0.2
复制代码

Hello world

新建一个文件demo.ts

var msg:string = "hello world";
console.log(msg)
复制代码

然后在文件位置打开命令行工具,运行命令

tsc demo.ts
复制代码

编译成功,会生成一个对应的demo.js文件,然后运行命令

node demo.js
复制代码

可以看到输出内容为

hello world
复制代码

后续的例子中,都需要先通过tsc命令编译文件,然后再通过node命令运行文件来查看运行结果,后面将不再赘述。

按照规定声明变量

用接口interface来抽象声明一个对象,表征一下要声明对象的要求,然后由具体的变量实现:

//定义一个接口叫Hero,这个类型必须包含一个id属性Number类型,一个name属性String类型
interface Hero{
    id: number,
    name: string,
}

//声明一个变量符合Hero类型
let Captain:Hero = {
    id: 1,
    name: 'Chris',
}

console.log(Captain);       //{id: 1,name: 'Chris'}
复制代码

如果定义变量时类型不符合,在编译时则会报错:

let Captain:Hero = {
    id: '1',
    name: 'Chris'
}
// Type 'string' is not assignable to type 'number'
复制代码

假若缺少相关属性类型,也会在编译时报错:

let Captain:Hero = {
    name: 'Chris'
}
// Property 'id' is missing in type '{ name: string; }' but required in type 'Hero'
// 在Hero类型中缺少id属性
复制代码

接口还可以规定方法的参数和返回值类型

function fn(id:number,name:string):Hero{
 return {
  id,
  name
 }
}
复制代码
function getHeroes():Hero[]{
    let heroList = [];
    for(let i=0;i<10;i++){
        let hero:Hero = {
            id: i+1,
            name: 'name' + i
        }
        heroList.push(hero)
    }
    return heroList
}

let heroes = getHeroes();

console.log(heroes);
复制代码

枚举

枚举成员自动赋值从0开始递增,也可手动赋默认值

enum Week {
    Mon,
    Tue = 2,
    Wed,
    Thu,
    Fri,
    Sat,
    Sun
}
复制代码
{
  '0': 'Mon',
  '2': 'Tue',
  '3': 'Wed',
  '4': 'Thu',
  '5': 'Fri',
  '6': 'Sat',
  '7': 'Sun',
  Mon: 0,
  Tue: 2,
  Wed: 3,
  Thu: 4,
  Fri: 5,
  Sat: 6,
  Sun: 7
}
复制代码

也可枚举字符串,每个成员都用字符串字面量

enum Week {
    Mon ="red",
    Tue ="orange",
    Wed ="yellow",
    Thu ="green",
    Fri ="blue",
    Sat ="indigo",
    Sun ="purple"
}
复制代码

也可以异构枚举,数字和字符串混合

enum Week {
    Mon ="1",
    Tue ="orange",
    Wed ="5",
    Thu ="green",
    Fri ="3",
    Sat ="indigo",
    Sun ="purple"
}
复制代码

一般枚举的使用场景在声明一些固定值的时候,通过枚举从而配置全局变量,便于在开发时引用或者修改。

类的用法

TS中提供了三种访问修饰符public,private,protected用来修饰属性和方法 public公有的,可以在任何地方被访问到,一般默认都是public private私有的,不能在声明类的外部访问 protected受保护的,和private类似,只在子类中允许被访问

class Cat {
    public name;
    public constructor (name){
        this.name = name;
    }
}

let Tom = new Cat('Tom');
console.log(Tom.name);

Tom.name = "Jerry";
console.log(Tom.name)
复制代码

上例中,name属性被设置为public,因此可以直接被访问到

class Cat {
    private name;
    public constructor (name){
        this.name = name;
    }
}

let Tom = new Cat('Tom');
console.log(Tom.name);  //Property 'name' is private and only accessible within class 'Cat'.
复制代码

name属性只能在Cat类中访问,不能在外部访问;但是还要注意,ts在编译之后的代码中并没有限制private属性外部的访问性

var Cat = /** @class */ (function () {
    function Cat(name) {
        this.name = name;
    }
    return Cat;
}());
var Tom = new Cat('Tom');
console.log(Tom.name);
复制代码

在子类继承中,也是不允许访问私有属性的

class Cat {
    private name;
    public constructor (name){
        this.name = name;
    }
}

class Tom extends Cat {
    constructor(name){
        super(name);
        console.log(this.name);
    }
}
//Property 'name' is private and only accessible within class 'Cat'.
复制代码

而如果将上文中private替换为protected,则允许子类进行访问 同时,如果构造函数被private修饰,则该类不允许被继承或实例化;如果构造函数被protected修饰,则该类只允许被继承

class Cat {
    public name;
    protected constructor (name){
        this.name = name;
    }
}

class Tom extends Cat {
    constructor(name){
        super(name);
    }
}

let George = new Cat('George');
console.log(George.name)
//Constructor of class 'Cat' is protected and only accessible within the class declaration.
//Cat类不能被实例化,只能继承
复制代码

抽象类

关键字abstract用于定义抽象类和抽象方法,同时抽象类不允许被实例化

abstract class Cat{
    public name;
    public constructor(name){
        this.name = name;
    }
    public abstract catchMouse();
}

let Tom = new Cat('Tom');
// Cannot create an instance of an abstract class.无法创建抽象类的实例。
复制代码

并且,抽象类的抽象方法必须被子类实现

abstract class Cat{
    public name;
    public constructor(name){
        this.name = name;
    }
    public abstract catchMouse();
}
class Tom extends Cat{
    public catchMouse(){
        console.log(`${this.name} runs to catch the mouse.`);
    }
}
let tom = new Tom('Tom');
tom.catchMouse();
复制代码

类与接口

一个类只能继承自另一个类;不同类之间有一些共有特性,可以把这个特性提取成接口,用implements来实现 举例来说,动物是一个类,猫是动物的一个子类,猫有抓老鼠的功能特性,那我们可以给猫添加一个抓老鼠方法;这时还有一个子类——蛇,它是动物的子类,也具有抓老鼠的功能特性,这时就可以考虑把抓老鼠方法提取作为一个接口,让猫类和蛇类去实现。

interface catchMouse{
    eat(name:string): string;
}
class Animal{}
class Cat extends Animal implements catchMouse{
    public name;
    public constructor(name){
        super();
        this.name = name;
    }
    eat(){
        return `${this.name} catch and eat mouse.`
    }
}
class Snack implements catchMouse{
    eat(){
        return 'catch mouse.'
    }
}
let tom = new Cat('Tom');
console.log(tom.eat());	//Tom catch and eat mouse.
复制代码

一个类还可以实现多个接口:

interface catchMouse{
    eat(name:string): string;
}
interface climbTree{
    climb():void;
}
class Cat implements catchMouse,climbTree{
    public name: string;
    constructor(name){
        this.name = name;
    }
    eat(){
        return `${this.name} catch and eat mouse.`
    }
    climb(){
        console.log(`${this.name} climbing tree.`)
    }
}
let tom = new Cat('Tom');
console.log(tom.eat());		//Tom catch and eat mouse.
console.log(tom.climb());	//Tom climbing tree.
复制代码

需要注意的是,Cat类在implements里要实现的类方法,都要一一实现,不能缺少,否则会报错。

本文简单介绍了有关TypeScript的基本用法,后续将继续介绍泛型等其他内容,欢迎大家关注哦~


❤️ 感谢大家

如果你觉得这篇内容对你挺有有帮助的话: 点赞支持下吧,让更多的人也能看到这篇内容(收藏不点赞,都是耍流氓 -_-) 关注公众号【前端优选】,定期为你推送好文。

本文使用 mdnice 排版

分类:
前端
标签:
分类:
前端
标签: