目录

一、 准备工作

二、 创建 ts  项目文件并运行

三、 五分钟上手 ts

四、 ts 相关要点

基本数据类型

非基本数据类型

接口与继承

类及继承

函数

泛型


一、 准备工作

        a. 安装node (在Windows上安装时务必选择全部组件,包括勾选Add to Path。)

                node -v (检查node版本及是否安装成功)

        b. 全局安装ts (安装之后可用命令: tsc 运行ts文件)

                yarn add global typescript (或者 npm install -g typescript )

                用 yarn 安装之前需安装yarn  相关介绍看上参考之前的文章,这里是跳转链接

二、 创建 ts  项目文件并运行

        a. 创建 ts 项目的专门目录, 建立index.ts文件(兼容js语法)

        b. 命令行运行ts文件: tsc index.ts (会发现文件夹下会生成同名js文件)

        c. 命令行运行js文件:node index.js (可以省略后缀,上同)

        d. 添加 tsconfig.json文件命令 : tsc --init  (告诉编译器以什么标准解析ts)

        e. 点击终端-->运行生成任务--> tsc:监视 (可以监控ts文件改动后自动编译生成对应js文件) 

三、 五分钟上手 ts

        可参考这篇文章

        index.ts 示例文件如下:


interface Person {
    firstName: string;
    lastName: string;
}

class Student {
    fullName: string;
    constructor(public firstName: string, public middleInitial: string, public lastName: string) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}


function greeter(person : Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);
console.log(document.body.innerHTML);

四、 ts 相关要点

        以下做简要介绍, 需要了解具体内容可自行查阅官网文档

基本数据类型

// ts 是 js 的超集:兼容js语法并加以扩展
console.log('hello,ts');

// 基本数据类型
// 字符串 数字 undefined null 布尔值
var a : string= 'str'
a = 'string'

let num : number = 2
num = 3

// undefined:js中声明但未赋值时结果;取对象上不存在的属性
let un:undefined = undefined

let nu:null = null 

let isDone: boolean = false;

console.log(a,num,un,nu,isDone);

非基本数据类型

// 数组
// var arr:Array = [1] // 不推荐(声明时必须传值)

var arr:[]=[]  // 表明arr 只能是空数组 下面俩行可 但不能push(1)
arr.length
arr.push()

var ids:number[]= [] // 表明arr 只能是承载number元素的数组
ids.push(33)
console.log(ids);

// 元组(规定长度、类型的数组)
let typeArr:[string, number]
typeArr = ['xiaowang',18]
// typeArr = ['xiaowang',18,‘小仙女’]  //报错 长度超出了

// 枚举(ts新增类型) ==> 生成一个相互引用的对象(键值互相可拿到对方)
enum types {
    typestring, // 默认索引从0开始
    typenumber,  // 索引为1
    typenull = 21, 
    typeundefined  // 索引为22
}
console.log(types);

// 使用场景:后台返回状态码,前台自动显示对应提示信息,无需if/switch判断
enum msgs{
    '成功' = 200,
    '账号错误' = 301,   
    '密码错误' = 402
 }
console.log(msgs);

// any 任意类型 (少用)
var type : any
type = 'xxx'
type = 9
type = []
type = true
console.log(type);

// void ==> 没有值
// 使用场景:规范一个函数没有返回值
let vts :void
// vts = void  // 只能设置成void或undefined
vts = undefined

// Function
var fun : Function = ()=>{}
fun = function(){console.log(1);}
var fun2 = function(){console.log(2);
}

接口与类型

不同点:

        类型别名 type 不仅可以用来表示基本类型,还可以用来表示对象类型;接口interface 仅限于描述对象类型。

interface使用“extends”扩展,type使用“&”继承 。

相同点:

        interface 和 type 都可以继承。

接口与继承

// 接口(限制对象)
// 定义接口
interface info{
    username : string,
    id : number,
    vip ?: boolean // 可选 布尔型
    readonly age : number, // readonly: 规定属性 只读不可更改
                          // const: 规定变量不可变
    sayhi() : void,

    // 给接口留有余地
    [props:string]:any  // 可选 任意(字符串类型)属性名且属性值(可为任意类型)
}   
// 使用接口  必须包含以上必选属性 且类型对应;不能添加未定义的属性
var obj : info = {
    username: 'wb',
    id : 1,
    vip : true,
    age :16,
    sayhi : ()=>{console.log('嗨');
    }
}
obj.id = 2
obj.vip = false
obj.prop1 = '1' // 符合接口中的定义: [props:string]:any  
obj.prop2 = 2   // 同上
console.log(obj);
obj.sayhi()

//  限制函数
// 定义
interface sayhiInt{
    (str:string):string  //限定:参数类型 返回值
}
// 使用
var sayhi : sayhiInt = function(s:string){
    return '你好' + s
}
console.log(sayhi('wb') );


 // 接口继承

// 定义vip
interface vipInt{
    isvip : boolean,
    vipType : number
}
// 定义 info
interface infoInt{
    username : string,
    id : number,
    vip ?: boolean // 可选 布尔型
    readonly age : number, // 规定属性 只读
                          // const 规定变量不可变
    sayhi() : void,
    // 给接口留有余地
    // 可选属性名(字符串类型)属性值(任意)
    [propsName:string]:any  
} 
// 定义 函数接口
interface sayhiInt {
    (str:string): string
}
// 继承以上俩个接口
interface vipinfoInt extends vipInt,infoInt{
    isadd : boolean
}
// 使用
let vipinfoData : vipinfoInt = {
    isvip : true,
    vipType : 3 ,
    username : 'ww',
    id : 2,
    age :19,
    sayhi:()=>{console.log('hi')    },
    isadd : true

}
console.log( vipinfoData );


// 混合类型 : 规范函数
interface icontInt{
    count : number,  // 元素属性
    () : void       // 函数属性
}
// 声明一个函数满足 icontInt的约束:需包含其中属性
let getcount = function():icontInt{
    
    let countFun = <icontInt> function(){
        countFun.count++
        console.log(countFun.count);
        
    }
    countFun.count = 1
   return countFun
}
console.log( getcount() );


类及继承

// 类的定义
class Info {
    userName: string
    id: number
    type: string
    age: number = 18
    
    // 构造函数
    constructor(u: string, i: number, t: string) {
        this.userName = u
        this.id = i
        this.type = t
    }
}

// 实例化对象
var Minfo = new Info('wb', 1, 'vip')
console.log(Minfo);
class Sayhi {
    hiFun() {
        console.log('你好');
    }
}

var hi = new Sayhi()
console.log(hi);

  类的继承:      

        a. 子类从基类中继承(extends)属性和方法,可以重写父类,也能写自身的属性

        b. 子类若有构造函数,必须调用 super(),会执行基类的构造函数。且在构造函数里访问 this的属性之前,要调用 super()

        c. 类可以创建出类型,与接口有类似之处,所以允许在使用接口的地方使用类

class Point {
    x: number;
    y: number;
}

interface Point3d extends Point {
    z: number;
}

let point3d: Point3d = {x: 1, y: 2, z: 3};

函数

        函数类型:参数类型返回值类型约束,可以规定形参和返回值的类型,如果函数没有返回任何值,必须指定返回值类型为void而不能留空。

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

       可选参数 lastName?: string  只能跟在必须参数后面  不传的话值为undefined :

function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

let result1 = buildName("Bob");  // works correctly now
let result2 = buildName("Bob", "Adams", "Sr.");  // error, too many parameters
let result3 = buildName("Bob", "Adams");  // ah, just right

       剩余参数 ...restOfName: string[] 收集到一个数组里:

function buildName(firstName: string, ...restOfName: string[]) {
  return firstName + " " + restOfName.join(" ");
}

let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");


// 省略号也会在带有剩余参数的函数类型定义上使用到:
let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;

泛型

        定义:根据形参推断出返回的类型,内部也只使用该类型的方法,注意规范避免某类型的方法。以下以泛型函数为例,也可有泛型类。

function identity<T>(arg: T): T {
    return arg;
}

// 给identity添加了类型变量T,T帮助捕获传入的类型(比如:number)
// 再次使用了 T 当做返回值类型,即参数类型与返回值类型是相同的

        泛型接口T:T用于泛型数据类型的约束 ,也可以约束类(构造函数);相当于形参的一部分  表示的是实际参数的类型。

        泛型变量:

function loggingIdentity<T>(arg: T): T {
    console.log(arg.length);  // Error: T doesn't have .length
    return arg;
}

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}

        泛型继承: 用于扩展类型 (定义一个接口 :包含 length属性,让一个泛型继承该接口 就有了length属性)

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);  // Now we know it has a .length property, so no more error
    return arg;
}

类型兼容:

1. 属性 ‘多的’ 对象能赋值给 ‘少的’ ,反之不行

interface Named {
    name: string;
}

let x: Named;
// y's inferred type is { name: string; location: string; }
let y = { name: 'Alice', location: 'Seattle' };
x = y;  // ok
y = x; // Error

2.参数 ‘少的’ 能赋值给参数 ‘多的’

let x = () => ({name: 'Alice'});
let y = () => ({name: 'Alice', location: 'Seattle'});

x = y; // OK
y = x; // Error, because x() lacks a location property

高级类型:

1. 交叉类型:&  将多个类型合并为一个类型

2. 联合类型:|  表示一个值可以是几种类型之一

function padLeft(value: string, padding: string | number) {
    if (typeof padding === "number") {
        return Array(padding + 1).join(" ") + value;
    }
    if (typeof padding === "string") {
        return padding + value;
    }
    throw new Error(`Expected string or number, got '${padding}'.`);
}

let indentedString = padLeft("Hello world", true); // errors during compilation

注意:如果一个值是联合类型,我们只能访问此联合类型的所有类型里共有的成员。

interface Bird {
    fly();
    layEggs();
}

interface Fish {
    swim();
    layEggs();
}

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim();    // errors, 不能确定一个 Bird | Fish 类型的变量是否有 fly方法

介于篇幅有限,对于 ts 剩余的内容,诸如:

 类型断言: as 用某个属性时,先断言该属性的对象存在

 命名空间namespace :空间内的变量要在外面使用 须export

 /// :使用多个 /// <reference path="..." /> 把不同文件地址里的命名空间合并处理

装饰器

声明文件: .d.ts  (declare)

等下次更新......

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐