一、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"
]
}
- 创建 tsconfig.json 文件 tsc --init 生成配置文件

- 点击菜单 任务-运行任务 点击 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> 来表示数组:  
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 };