Typescript基础介绍, 安装,数据类型以及函数

723 阅读9分钟

一、Typescript 介绍

typescript是由Anders Hejlsberg开发的,他也是c#语言开发团队的核心成员之一。

TypeScript是一种由微软开发和维护的免费开源编程语言。它是一个强类型的JavaScript超集,可编译为纯JavaScript。它是一种用于应用级JavaScript开发的语言。对于熟悉c#、Java和所有强类型语言的开发人员来说,TypeScript非常容易学习和使用。

TypeScript可以在任何浏览器、主机和操作系统上执行。TypeScript不是直接在浏览器上运行的。它需要一个编译器来编译和生成JavaScript文件。TypeScript是带有一些附加特性的ES6 JavaScript版本。

  • ts由微软开发的
  • 一门编程语言
  • ts是js的超级 遵循es6 es5的规范 ts扩展了js的语法
  • ts像 java .net 面向对象的语言 (规范 模块化 工程化),可以让 js 开发大型企业项目
  • 开发大型的企业项目 vue3.0 用ts的目的
  • 谷歌也在大力的支持ts的推广 谷歌ng2.x就是基于ts的语法
  • 最新的vue react 也可以集成ts

介绍

TypeScript 和 JavaScript 的区别是什么?

Typescript 是 JavaScript 的超集,可以被编译成 JavaScript 代码。 用 JavaScript 编写的合法代码,在 TypeScript 中依然有效。Typescript 是纯面向对象的编程语言,包含类和接口的概念。 程序员可以用它来编写面向对象的服务端或客户端程序,并将它们编译成 JavaScript 代码。

TypeScript 引入了很多面向对象程序设计的特征,包括:

  • interfaces 接口
  • classes 类
  • enumerated types 枚举类型
  • generics 泛型
  • modules 模块

主要不同点如下:

  • TS 是一种面向对象编程语言,而 JS 是一种脚本语言(尽管 JS 是基于对象的)。
  • TS 支持可选参数, JS 则不支持该特性。
  • TS 支持静态类型,JS 不支持。
  • TS 支持接口,JS 不支持接口。

二、 使用Typescript的一些优点和缺点?

静态类型检查有明显优势 以及让代码可读性变高

TypeScript有以下优点:

  • 它提供了可选静态类型的优点。在这里,Typescript提供了可以添加到变量、函数、属性等的类型。
  • Typescript能够编译出一个能在所有浏览器上运行的JavaScript版本。
  • TypeScript总是在编译时强调错误,而JavaScript在运行时指出错误。
  • TypeScript支持强类型或静态类型,而这不是在JavaScript中。
  • 它有助于代码结构。
  • 它使用基于类的面向对象编程。
  • 它提供了优秀的工具支持和智能感知,后者在添加代码时提供活动提示。
  • 它通过定义模块来定义名称空间概念。

TypeScript有以下缺点:

  • TypeScript需要时间来编译代码。
  • TypeScript不支持抽象类。
  • 如果我们在浏览器中运行TypeScript应用程序,需要一个编译步骤将TypeScript转换成JavaScript。

为什么要用 TypeScript ?

  • TS 在开发时就能给出编译错误, 而 JS 错误则需要在运行时才能暴露。
  • 作为强类型语言,你可以明确知道数据的类型。代码可读性极强,几乎每个人都能理解。
  • TS 非常流行,被很多业界大佬使用。像 Asana、Circle CI 和 Slack 这些公司都在用 TS。

TypeScript 和 JavaScript 哪个更好?

由于 TS 的先天优势,TS 越来越受欢迎。但是TS 最终不可能取代 JS,因为 JS 是 TS 的核心。

选择 TypeScript 还是 JavaScript 要由开发者自己去做决定。如果你喜欢类型安全的语言,那么推荐你选择 TS。 如果你已经用 JS 好久了,你可以选择走出舒适区学习 TS,也可以选择坚持自己的强项,继续使用 JS。

三、Typescript 环境安装 编译 运行

3.1 Typescript 安装 编译

 npm i typescript -g     //   yarn global add typescript

检查版本 : tsc -v

通过命令编译typescript文件

 tsc + ts文件

3.2 是否可以将多个.ts文件合并成一个.js文件?

需要添加——outFile [OutputJSFileName]编译选项

tsc --outFile comman.js file1.ts file2.ts file3.ts  

上面的命令将编译所有这三个.ts文件和结果将存储在一个comman.js文件中,在这种情况下,当我们不提供输出文件名像下面的命令。

tsc --outFile file1.ts file2.ts file3.ts  

然后file2.ts和file3.ts将被编译,并将输出放在file1.ts中,现在是file1.ts包含JavaScript代码。

3.3 能否自动编译.ts文件,并实时修改.ts文件?

自动实时根据.ts文件变化自动编译.ts文件是可以的。这可以通过使用——watch compiler选项来实现

tsc --watch file1.ts  

tsc --watch --outFile test/file1.js  file1.ts
//把 file1.ts文件打包到文件夹test下的file1.js, 并实时监控

上面的命令首先编译file1为file1.js,并注意文件的变化,如果检测到任何更改,它将再次编译文件。

3.4 Typescript 开发工具 Vscode 自动 编译.ts 文件

什么是tsconfig.son文件 tsconfig.son文件是json格式的文件。tsconfig.json文件中,我们可以指定各种选项告诉编译器如何编译当前项目。目录中存在tsconfig.json文件,表明该目录是TypeScript项目的根目录。 下面是一个示例tsconfig.json文件。

{  
   "compilerOptions": {  
      "declaration": true,      
      "emitDecoratorMetadata": false,      
      "experimentalDecorators": false,      
      "module": "none",      
      "moduleResolution": "node"  
      "removeComments": true,  
      "sourceMap": true  
   },  
   "files": [  
      "main.ts",  
      "othermodule.ts"  
    ]  
}  
  1. 创建 tsconfig.json 文件 tsc --init 生成配置文件
    介绍
  2. 点击菜单 任务-运行任务 点击 tsc:监视-tsconfig.json 然后就可以自动生成代码 了

介绍

1.3 Typescript 开发工具 HBuilder 自 动编译.ts 文件

省略

三. typeScript中的数据类型以及定义

typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验,在typescript中主要给我们提供了以下数据类型

比较es5里数据类型: 基本: number,string,boolean,undefined,null,symbol bigint 复杂: Object,Array

所有这些类型都是动态的:您可以在运行时使用它们。

TypeScript 在 JavaScript 基础上增加了一层:静态类型。它只存在于编译的时候或者源代码类型检查的时候。每一个有静态类型的储存(变量或者属性)地方都可以预知它的值。类型检查确保实现类型推断,不用运行代码就能进行静态类型检查。

举个例子,如果函数f(x)的参数x具有静态数字类型,则函数调用f('abc')是非法的,因为参数'abc'是错误的静态类型参数。

ts的数据类型

  • 布尔类型(boolean)

  • 数字类型(number)

  • 字符串类型(string)

  • 数组类型(array)

  • 元组类型(tuple)

  • 枚举类型(enum)

  • 任意类型(any)

  • null 和 undefined

  • void类型:不返回任何类型值的函数的返回类型

  • never类型

数据类型的定义

类型标注

类型标注在变量的冒号后面。冒号后面的静态类型标注描述了这个变量可以有什么值。下面一个例子表示这个变量只能储存数字类型 var age:number = 18;

类型推断

在 TypeScript 中,即使所有变量你都写静态类型,但你不需要全部明确写它的静态类型。

TypeScript 经常可以推断出它。 例如,如果你写 let x = 123; 然后TypeScript推断x具有数字静态类型。

普通类型在赋值过程中改变类型是不允许的


//类型推论 (如果变量已经赋值,那么不需要明确指定他的类型,会根据值自动判断是什么静态类型)
let username = 'tom';

// 类型标注(指定变量类型,会通过静态类型检测变量)
let fruit: string;

var age:number = 18;
var name:string = 'abc';
var name:string = `hello`;
var flag:boolean = false;
var u:undefined = undefined;
var n:null = null;

如果定义name会报错,提示 error TS2451: Cannot redeclare block-scoped variable 'name'

var name:string = 'abc'; 报错

redeclare block-scoped variable 'name' 原因 在默认状态下,typescript 将 DOM typings 作为全局的运行环境,所以当我们声明 name时, 与 DOM 中的全局 window 对象下的 name 属性出现了重名。因此,报了 error TS2451: Cannot redeclare block-scoped variable 'name'. 错误。

解决方法:

  • 方法一:

将运行环境由 DOM typings 更改成其他运行环境。 我们可以在 tsconfig.json 中做一下声明:

    {
        "compilerOptions": {
            "lib": [
                "es2015"
            ]
        }
    }
  • 方法二:

既然与全局的变量出现重名,那我们将脚本封装到模块(module)内。module 有自己的作用域,自然不会与全局作用域的变量产生冲突。

const name = 'youthcity';
function greeter(name:string) {
    return `Hello ${name}`;
}
console.log(greeter(name));
export {};

4.1 布尔类型(boolean)


 /*
    es5的写法 (正确写法)  ts中(错误写法)
        var flag=true;
        flag=456;
    */

    /*
     typescript中为了使编写的代码更规范,更有利于维护,增加了类型校验
     写ts代码必须指定类型
    var flag:boolean=true;
    // flag=123;  //错误
    flag=false;  //正确
    console.log(flag);
    */

4.2 数字类型(number)

 /*
        var num:number=123;
        num=456;
        console.log(num);  /正确/
        num='str';    //错误
*/

4.3 字符串类型(string)

 /*
        var str:string='this is ts';
        str='haha';  //正确
        str=true;  //错误
   */

4.4 任意类型(any)

 var num:any=123;
num='str';
num=true;
console.log(num) */

//任意类型的用处
/* var oBox: any = document.getElementById('box');
oBox.style.color = 'red'; 

4.5 联合类型 表示值可以符合多种类型

let a3:string | number[];    
//number[]数组
a3 = 'abc';
a3 = [1,2,3];
function fun2(a3:string | number[]){
    return a3.length;     
     //对于联合类型返回符合所有类型里共有的属性和方法
};
fun2(a3)

4.6 数组类型(array) ts中定义数组有多种方式

// var arr=['1','2'];  //es5定义数组


// 1.第一种定义数组的方式 = 基础类型 + 方括号
var arr1:number[]=[11,22,33];  ////元素为数字的数组
console.log(arr);

var arr1_1:string[] = ['1','2','3'];   //元素为字符串的数组

//2.第二种定义数组的方式  =  数组泛型 
// 也可以使用数组泛型(Array Generic) Array<elemType> 来表示数组:&emsp;&emsp;
var arr2:Array<number>=[11,22,33];
console.log(arr2)

//3、第三种  -- any

var arr3:any[]=['131214',22,true];
console.log(arr3);

// 4. 元组
// 数组中的数据类型必须和规定的类型顺序对应起来
let arr:[number,string]=[123,'this is ts'];


//5 . 接口数组 - 可索引接口 对数组的约束

interface NumberArray{
    [index:number]:number
}
let arr: NumberArray = [1,1,2,3,4]

// 接口解释:NumberArray 表示:只要 index 的类型是 number,那么值的类型必须是 string。

4.7 元组类型(tuple) 属于数组的一种

它允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 中括号中规定数组中数据的类型和顺序

//元祖类型
let arr:[number,string]=[123,'this is ts'];
console.log(arr);  

4.8 枚举类型(enum)

枚举是一种数据类型,允许我们定义一组命名常量。使用枚举可以更容易地记录意图,或者创建一组不同的案例。它是相关值的集合,可以是数值或字符串值。

// 比如:星期, 付款状态(0:支付中, 1:支付成功,2:支付失败)

enum 枚举名{ 
标识符[=整型常数], 
标识符[=整型常数], 
... 
标识符[=整型常数], 
} ;     
enum Gender {  
  Male,  
  Female  
  Other  
}  
console.log(Gender.Female); // : 1  
// 我们还可以通过enum值的number值来访问它
console.log(Gender[1]); // : Female  
 /*
    enum Flag {success=1,error=2};
    let s:Flag=Flag.success;

    console.log(s);

    enum Flag {success=1,error=2};
        let f:Flag=Flag.error;
        console.log(f);

    enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat}; 
    console.log(weekday.sat)
*/

4.9 undefined

// var num:number;
// console.log(num)  //输出:undefined   报错

// 定义没有赋值就是undefined
// var num:undefined;
// console.log(num)  //输出:undefined  //正确

var num:number | undefined;
num=123;
console.log(num);

4.10 void类型

typescript中的void表示没有任何类型,一般用于定义方法的时候方法没有返回值。

// es5的定义方法
/* function run(){
    console.log('run')
}
run(); */

表示方法没有返回任何类型

/* 
//正确写法
function run():void{
    console.log('run')
   }
run();
*/

//错误写法
/*
    function run():undefined{
        console.log('run')
    }
    run();
*/

//正确写法
/*function run():number{
    return 123;
 }
 run();
*/

4.11 never类型

其他类型 (包括 null 和 undefined)的子类型,代表从不会出现的值。 这意味着声明never的变量只能被never类型所赋值。

var a: never;
a = (() => {
    throw new Error('错误');
})()

五、typeScript中的函数

5.1、函数的定义
5.2、可选参数
5.3、默认参数
5.4、剩余参数
5.5、函数重载
5.6、箭头函数  es6

5.1、函数的定义

//es5定义函数的方法
   /*
    //函数声明法
        function run(){
            return 'run';
        }
    //匿名函数
        var run2=function(){
            return 'run2';
        }
   */

//ts中定义函数的方法
 //函数声明法
        //正确写法
        // function run():string{
        //     return 'run';
        // }

        //错误写法
        // function run():string{
        //     return 123;
        // }

//匿名函数
    // var fun2=function():number{
    //     return 123;
    // }
    // alert(fun2());

ts中定义方法传参 限制参数类型 param:string;

限制返回类型 :string

function getSex(name: string): string {
    return '男';
 
}
  /*
        function getInfo(name:string,age:number):string{
                return `${name} --- ${age}`;
        }
        alert(getInfo('zhangsan',20));
    */


    var getInfo=function(name:string,age:number):string{
        return `${name} --- ${age}`;
    }
       
    alert(getInfo('zhangsan',40));

//没有返回值的方法
    function run():void{
        console.log('run')
    }
    run();


5.2、方法可选参数

es5里面方法的实参和行参可以不一样,但是ts中必须一样,如果不一样就需要配置可选参数


function getInfo(name:string,age?:number):string{
        if(age){
            return `${name} --- ${age}`;
        }else{
            return `${name} ---年龄保密`;
        }
}
alert(getInfo('zhangsan'))
alert(getInfo('zhangsan',123))
       

注意:可选参数必须配置到参数的最后面

5.3、默认参数 可选参数

es5里面没法设置默认参数,es6和ts中都可以设置默认参数

  function getInfo(name:string,age:number=20):string{
            if(age){
                return `${name} --- ${age}`;
            }else{
                return `${name} ---年龄保密`;
            }

}

// alert( getInfo('张三'));
alert( getInfo('张三',30));

5.4、剩余参数

/*  function sum(a:number,b:number,c:number,d:number):number{
        return a+b+c+d;
    }
    alert(sum(1,2,3,4)) ; */

    //三点运算符 接受新参传过来的值

        function sum(...result:number[]):number{    
               //方式一
                // var sum=0;
                // for(var i=0;i<result.length;i++){
                //     sum+=result[i];  
                // }
                // return sum; 
                
                //方式二
            return result.reduce(function(prev, curr){
                return prev + curr;
            },0);
        }
        alert(sum(1,2,3,4,5,6)) ;
 

      
function sum(a:number,b:number,...result:number[]):number{           
        var sum=a+b;
        for(var i=0;i<result.length;i++){
            sum+=result[i];  
        }
        return sum;
    }

    alert(sum(1,2,3,4,5,6)) ;
var arr1:number[]=[11,22,33]; 
// alert(sum(...arr1)) ; //错误
alert(sum(1,2,...arr1)) ; //正确 */
  

5.5、ts函数重载

TypeScript支持函数重载。但是它的实现很奇怪,当我们在TypeScript中执行函数重载时,我们只能实现一个带有多个签名的函数。

函数重载:以参数数量或类型区分多个同名函数 先声明,再实现


//es5中出现同名方法,下面的会替换上面的方法
/*
function css(config){
}
function css(config,value){
}
*/

//带有字符串类型参数的函数  
function add(a:string, b:string): string;    
  
//带有数字类型参数的函数
function add(a:number, b:number): number;    
  
//函数定义
function add(a: any, b:any): any {    
    return a + b;    
} 

在上面的例子中,前两行是函数重载声明。它有两次重载,第一个签名的参数类型为string,而第二个签名的参数类型为number。第三个函数包含实际实现并具有any类型的参数。任何数据类型都可以接受任何类型的数据。然后,实现检查所提供参数的类型,并根据供应商参数类型执行不同的代码段

5.6、类型别名 type

type str = string; //基本类型 
var username:str = 'laney';
function fun6(name:str):str{
    return 'hello ' + name;
};
fun6(name); 
type abc = string | number[];  // 联合类型
type num = number;
function fun7(a3:abc):num{
    return a3.length;      //对于联合类型返回符合所有类型里共有的属性和方法
};
fun7([1,2,3])

type 会给一个类型起个新名字。 type 有时和 interface 很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型。

type Name = string; // 基本类型
type NameResolver = () => string; // 函数
type NameOrResolver = Name | NameResolver; // 联合类型

function getName(n: NameOrResolver): Name {
    if (typeof n === 'string') {
        return n;
    } else {
        return n();
    }
}

同接口一样,类型别名也可以是泛型 - 我们可以添加类型参数并且在别名声明的右侧传入:

type Container = { value: T };