TypeScript
TypeScript和JavaScript区别
TypeScript | JavaScript |
---|---|
JavaScript 的超集用于解决大型项目的代码复杂性 | 一种脚本语言,用于创建动态网页。 |
可以在编译期间发现并纠正错误 | 作为一种解释型语言,只能在运行时发现错误 |
强类型,支持静态和动态类型 | 弱类型,没有静态类型选项 |
最终被编译成 JavaScript 代码,使浏览器可以理解 | 可以直接在浏览器中使用 |
支持模块、泛型和接口 | 不支持模块,泛型或接口 |
支持 ES3,ES4,ES5 和 ES6 等 | 不支持编译其他 ES3,ES4,ES5 或 ES6 功能 |
社区的支持仍在增长,而且还不是很大 | 大量的社区支持以及大量文档和解决问题的支持 |
1、强类型与弱类型(类型安全)
强类型:
语言层面限制函数的实参类型必须和形参类型相同
:强类型不允许任何形式的隐式转换
强类型优势
- 错误更早暴露
- 代码更智能,编码更准确
- 重构更牢靠
- 减少不必要的类型判断
弱类型:
语言层面不会限制实参类型
:弱类型允许隐式转换
弱类型问题
- 程序中的一些类型问题需要等到运行时才能发现
- 类型不明确造成函数功能有可能发生改变
2、静态类型与动态类型(类型检查)
静态类型:
变量在声明时类型就是确定的,且声明之后类型不可更改
动态类型:
运行阶段才能明确类型,且变量类型可以随时发生变化
:变量是没有类型的,变量中存放的值是有类型的
不同语言类型划分
3、JavaScript自有类型系统问题
弱类型且动态类型,缺失了类型系统的可靠性
4、Flow静态类型检查方案
javascript的类型检查器
5、TypeScript语言规范与基本应用
TypeScript是JavaScript的超集(扩展集),前端领域的第二语言、渐进式语言
优点
- 任意一种JavaScript运行环境都支持
- 功能更强大,生态更健全完善
缺点
- 语言本身多了很多概念
- 项目初期,会增加一些成本
使用
安装和启动
yarn init --yes
yarn add typescript --dev
//a.ts
const hello=(name:string)=>{
console.log(`hello,${name}`);
}
hello('TypeScript')
//控制台输入yarn tsc a.ts//根目录下,且该目录不含中文。 生成
//a.js
var hello = function (name) {
console.log("hello,".concat(name));
};
hello('TypeScript');
配置文件
yarn tsc --init
生成tsconfig.json文件
"target": "es2016", //把所有新特性转换成es6标准的代码
"module": "commonjs", //输出代码采用什么方式模块化
"rootDir": "src", // 配置源代码的文件夹
"outDir": "dist", //编译结果输出到的文件夹
"sourceMap": true, //开启源代码映射
"strict": true, //严格模式
原始数据类型
const a:string='foo'
const b:number=10
const c:boolean=true
// const d:boolean=null //严格模式下不行
const e:void=undefined
const f:null=null
const g:undefined=undefined
const h:symbol=Symbol()//es2016新增
const i:bigint=123n //es2020新增
typeScript显示中文错误消息
yarn tsc --locale zh-CN
或者VS code设置搜索typescript locale统一更改为zh-CN //一般不推荐
TypeScript object类型
除了原始类型的其他类型
用对象字面量方式或者接口来定义
const obj:object=function(){}//[] //{}
const obj:{foo:number,bar:string}={foo:123,bar:'string'}
TypeScript数组类型
const arr1:Array<number>=[1,2,3]
const arr2:number[]=[1,2,3]
function sum(...args:number[]){
console.log(111);
return args.reduce((prev,current)=>prev+current,0)
}
TypeScript元组类型
const tuple:[number,string]=[18,'str']
TypeScript枚举类型
一般使用对象模拟枚举
// 定义一个数字枚举
enum enumConst{
up = 1,
down,
left = 10,
right
};
console.log(enumConst[1]);
console.log(enumConst[2]);
console.log(enumConst[3]);
console.log(enumConst[4]);
console.log(enumConst[44]);
// 输出:
// up
// down
// left
// right
// undefined
console.log(enumConst.up);
console.log(enumConst.down);
console.log(enumConst.left);
console.log(enumConst.right);
// 输出:
// 1
// 2
// 10
// 11
TypeScript函数类型
function func1(a:number,b:number):string{
return 'func1'
}
function func2(a:number,b:number=10):string{//默认(必须出现在最后)
return 'func3'
}
function func3(a:number,b?:number):string{//可选(必须出现在最后)
return 'func3'
}
function func4(a:number,b?:number,...rest:number[]):string{//可选(必须出现在最后)
return 'func4'
}
const func5:(a:number,b:number)=>string=function(a:number,b:number):string{
return 'func5'
}
TypeScript任意类型
function any1(value:any){//轻易不使用
return value
}
TypeScript类型断言
类型断言不是类型转换,编译后就不存在
const nums=[100,200]
const res=nums.find(i=>i>1)
const num1=res as number
const num2=<number>res //jsx不能使用
TypeScript接口 interface
约定对象成员及成员类型
:用来为有结构的数据做类型约束
interface Post {
title: string//可以为; , 也可以不要符号
name: string
age: number
sex?:number//可选成员
readonly id:string//readonly只读成员,后续不可修改
[key:string]:string//动态成员,示例里是指string类型的键值和值
}
function printPost(post: Post) {
console.log(post.title);
console.log(post.name);
console.log(post.age);
}
printPost({
title: 'happy study day',
name: 'zangsan',
age: 18
})
TypeScript 类 的基本使用
class Person{
//类属性必须要有初始值
public name:string//name:string='init name'
protected age:number //保护属性,可以被子类访问
private id:string //私有属性,只能内部访问
constructor(name:string,id:string){//通过构造器赋值
this.name=name
this.age=18
this.id=id
}
sayHi(msg:string):void{
console.log(` I am ${this.name},age ${this.age}`);
console.log(this.id);
}
}
class Son extends Person{
constructor(name:string,id:string){
super(name,id)
console.log(this.age);
}
}
let tom=new Person('tom','abc111')
console.log(tom.name);
console.log(tom.age);//属性“age”受保护,只能在类“Person”及其子类中访问。
console.log(tom.id);//属性“id”为私有属性,只能在类“Person”中访问。
TypeScript类与接口
interface EatAndRun{
eat(food:string):void
run(distance:number):void
}
interface See{
see(color:string):void
}
class Person implements EatAndRun,See{
eat(food:string):void{
console.log(`吃西瓜:${food}`);
}
run(distance:number):void{
console.log(`跳绳:${distance}`);
}
see(color:string):void{
console.log(`跳绳:${color}`);
}
}
class Animal implements EatAndRun{
eat(food:string):void{
console.log(`吃:${food}`);
}
run(distance:number):void{
console.log(`跳:${distance}`);
}
}
TypeScript抽象类
//父类有抽象方法子类必须实现
abstract class Animal1{
eat(food:string):void{
console.log(`吃:${food}`);
}
abstract run(distance:number):void
}
class Dog extends Animal{
run(distance:number):void{
console.log('爬行',distance);
}
}
const dog=new Dog
dog.eat('骨头')
dog.run(100)
TypeScript泛型
在定义函数接口类时没有指定类型,在使用时定义
function ab(length:number,value:number):number[]{
const arr=Array<number>(length).fill(value)
return arr
}
function abc(length:number,value:string):string[]{
const arr=Array<string>(length).fill(value)
return arr
}
function abcd<T>(length:number,value:T):T[]{
const arr=Array<T>(length).fill(value)
return arr
}
// const res=ab(3,10)
const res=abc(3,'str')
// const res=abcd<string>(3,'aaa')
TypeScript类型声明
成员定义时未声明明确的类型,在使用时声明
import {camelCase} from 'lodash'
declare function camelCase(input:string):string