1.介绍
ts是js的超集,他融合了其他语言的优势,将js带到了一个新的高度
js,es,ts的关系:ECMAScript是JavaScript的标准,TypeScript是JavaScript的超集
2. 为什么使用ts?
1. 发现问题
js---运行后报错 ts---运行之前可检查出错误(静态类型检查)
2. 非异常故障
错别字,未调用函数,基本逻辑错误
const user = {
name:'小明',
age:26
}
user.location; //js返回undefined
//ts提示错误,location未定义
function test(){
return Math.random <0.5
//少写了()---ts报错---未调用函数的检查
}
const value = Math.random()<0.5?'a':'b'
if(value !== 'a'){ //ts提示一直走的false
}else if(value === 'b'){
}
3.使用
1.工具:vscode、nodejs、ts编译器(npm安装)
2. 优化编译(按需设置):
ts和js文件冲突问题,变量、函数名相同提示重复声明 终端运行生成配置文件:tsc --init
类型错误:将严格模式关闭tsconfig.json:strict:false
自动进行编译:终端运行:tsc --watch
当出现错误时不再进行编译:tsc --noEmitOnError 需要编译的文件名
3. 定义显示类型
function test(person:string,date:Date){
console.log(person,date)
}
//调用时,必须类型相符
test('abc',new Date()) //仍报错--new Date()自动转为字符串--自动类型推断
自动类型推断
const msg = 'abc' //未定义类型,但是自动推断为string
msg = 123 //类型不一致,不可将number类型赋值到string类型
function test(name:string,age:24|25|26){
}
const person = {
name:'小红',
age:26 //推断为数字类型 任意数字
}
test(person.name,person.age) //报错age类型不相符
test(person.name,person.age as 26) //在任意位置添加类型推断
const person = {
name:'小红',
age:26 as 26
}
4. 降级编译---考虑某些浏览器低版本兼容
tsconfig.json---'target':'es2016' 修改为es5则编译为es5,浏览器兼容es5的都可以运行
4. 常用类型
string字符串,number数字,boolean布尔,null不存在,undefined未初始化的值
any 任何类型 :不希望某个特定值导致类型检查错误(禁用所有的类型检查)
unknown 未知类型
bigint 大数
symbol 唯一值
never 不应该存在的状态 类型缩小到没有时可用never做详尽的检查
数组: type[] Array<type>--泛型
let arr:number[] = [1,2,3]
let arr2:Array<number> = [1,2,3]
函数 参数类型注释,返回值类型注释
function test(name:string){ //参数类型注释
console.log(name)
}
function test1(name:string):number{ //返回值类型注释
console.log(name)
return 123 //一般情况下不需要显示定义,自动推断
}
//匿名函数
const names=['小红','小明','小李']
names.forEach((item)=>{ //自动类型为string类型--上下文类型
console.log(item.toUpperCase)
})
function(fn:(a:string)=>void){
//约束传进来的函数类型
}
//
type Func = {
name:string
(a:number):void
}
function(fn:Func)
对象 {key1:type, key2:type, ...}
function test(obj:{name:string,age?:number}){
//加问号可加可不加,否则必须和类型定义时一致,不可增减
console.log(obj.age?.toLowerCase()) //if(obj.age !== undefined)
}
联合类型union
function test(id: number | string){
console.log(id)
}
test(123) //既可以是数字,也可以是字符串
test('123')
类型别名 type 给类型一个名字,以便重复使用
type Person = { //首字母大写
name:string,
age:number
}
const obj:person = {name:'小明',age:26}
类型别名扩展 通过&
type Animal = {
name:string
}
type Bear = Animal & {
honey:boolean
}
const bear:Bear = {
name:'熊大',
honey:true
}
接口 interface
interface Point{
x:number
y:number
}
const point:Point = {x:10,y:15}
扩展接口 通过extends
interface Animal {
name:string
}
interface Bear extends Animal {
honey:boolean
}
const bear:Bear = {
name:'熊大',
honey:true
}
添加新的字段:interface同名的方式,type创建后不可更改
interface Person {
name:string
}
interface Person {
age:number
}
const meinv:Person = {
name:'小红',
age:26
}
//type类型创建后不可更改
类型断言 获得的值ts无法识别他的类型 对象的类型: Web API 接口参考 | MDN
const myCanvas = doucument.getElementById('my_canvas') as HTMLCanvasElement
const myCanvas = <HTMLCanvasElement>doucument.getElementById('my_canvas')
文字类型
//字符串文字类型
function test(value:'left'|'right'){
}
test('left') //只能传入left或者right
//数字文字类型
function test(a:sting):0|1{
return a === 'hello'? 0:1
}
枚举 enum js中没有的
enum Direction{
Up = 1,
Down,
Right,
Left
}
console.log(Direction.Up,Direction.Down,Direction.Right,Direction.Left)//1,2,3,4
类型缩小 从宽类型转换为窄类型
if语句中的padding仅为数字类型,此时typeof类型缩小也是类型保护/守卫
构造签名
//定义一个类
class Ctor {
s:string
constructor(s:string){
this.s = s
}
}
type testCons = {
new (s:string):Ctor //构造函数签名
}
function fn(ctor:testCons){
return new ctor('hello')
}
const f = fn(Ctor)
console.log(f.s) //'hello'
泛型函数-类型推断 两个值类型之间存在关系
//输出的类型与参数的类型保持一致
function test<Type>(arr:Type[]:Type|undefined):Type|undefined{ //此处的Type可写为任意单词
return arr[0]
}
test([]) // 此时Type为undefined
test(['h','e','l']) // 此时Type为string
test([1,2,3]) // 此时Type为number
//多个泛型
function map<In,Out>(arr:In[],func:(arg:In)=>Out):Out[]{
return arr.map(func)
}
map(['1','2'],(n)=>parseInt(n))//In为字符串,Out为数字