概述
-
解决JavaScript类型系统的问题
-
大大提高代码可靠程度
强类型与弱类型
-
类型安全
-
强类型:
- 语言层面限制函数的实参类型必须与形参类型相同
- 有更强的类型约束
- 不允许任意的隐式类型转换
弱类型:
- 语言层面不限制实参类型
- 几乎没有约束
- 允许任意的隐式类型转换(理解)
一、安装
//安装
npm i -g typescript
//检查安装是否成功
tsc -v // Version ****
新建test.ts文件,输入代码并执行
const hello = (name: string)=>{
console.log("hello:",name)
}
hello('顾哥哥')
//执行ts文件
tsc test
发现多出了test.js文件
二、ts语法
1、原始数据类型和any类型
基本类型(单类型):
- String
- Number(NaN也是一种number,非number)
- Boolean
- Null
- Undefined
- BigInt
- Symbol
引用类型:
- object。里面包含的 function、Array、Date。
let isDOne:boolean = false
let age:number = 10
let firstName:string = "顾哥哥"
let msg:string = `hello, ${firstName}`
let u:undefined = undefined
let n:null = null
let getName:Object = (name:String)=>{
console.log(name)
}
//未明确类型是使用any
let notsure:any = 4
notsure = '猪猪'
notsure = null
notsure = undefined
notsure = getName
2、数组和元组
let arrOfNumbers:number[] = [1,2,3,'123'] //不可,元素必须为number
arrOfNumbers.push('123')//不可,进入元素必须为number
//元组
let user:[string,number] = ['111',111]
user.push('111') //仅能添加已定义类型其中一种
user.push(22)
user.push(undefined)//不可,进入元素必须为string/number
3、Interface接口
interface IPerson {
name:string;
age:number;
tel?:number;//?可选 代表 (不强制实现该属性)
readonly id?:number; //readonly只读,赋值后不可改变
}
let viking:IPerson = {
name: 'viking',
age:20,
}
4、Function函数
function add(x: number, y: number):number{
return x + y
}
add(1,2,3)//×error: 不能多加参数
let result = add(1,2)
//如何实现可选参数
function add2(x: number, y: number, z?:number ):number{
if( typeof z === 'number'){
return x+y+z
}
return x + y
}
// 声明函数类型
let add3:(x: number, y: number, z?:number )=>number = add
使用interface来描述函数
// 使用interface描述函数
interface ISum {
(x: number, y: number, z?:number ):number
}
let add4:ISum = (x: number, y: number):number{
return x + y
}
5、类型(类型推论、联合类型和类型断言)
//类型推论 在初始赋值未指定类型是会推测一个类型
let str = '123'
str = 1213 //error:已被推测为字符串,不可赋值为数字
//union types | 在未确定类型时,只能访问联合类型共有属性或方法
let numberOrString : number | string
numberOrString = 'abc'
numberOrString = 123
//类型断言 使用as指定联合类型中的变量类型 , 且编译器不应该报错
//可以使用typeof instance判断数据类型,提高代码容错率
function getLength(input : string | number):number{
const str = input as string
if(str.length){
return str.length
}else {
const number = input as number
return number.toString().length
}
}
6、class和接口
// 类(class)定义了一切事物的抽象特点
// 对象(Object) 类的实例
// 面向对象
//public private protected protected子类可以访问方法
// 类(class)定义了一切事物的抽象特点
// 对象(Object) 类的实例
// 面向对象
//public private protected protected子类可以访问方法
//接口对类的内容抽象
//累可以使用implements实现接口
//1、比如某些类中存在某些共性
class Car{
switchRadio(trigger: Boolean){
}
}
class Radio {
switchRadio(trigger: Boolean){
}
}
//2、抽离出switchRadio特性
interface Radios {
switchRadio(trigger: Boolean): void
}
//类实现 接口
class Cellphone implements Radios {
switchRadio(trigger: Boolean){
}
}
//继承多个接口
interface Radios1 {
switchRadio1(trigger: Boolean): void
}
interface Radios2 {
switchRadio2(trigger: Boolean): void
}
class Cellphone1 implements Radios1,Radios2 {
switchRadio1(trigger: Boolean){
}
switchRadio2(trigger: Boolean){
}
}
//接口继承接口
interface Radios3 extends Radios1 {
switchRadio2(trigger: Boolean){
}
}
7、枚举
enum Direction {
Up,
Down,
Left,
Right
}
//枚举成员会自动被赋值为0,1,2,3,4……
console.log(Direction.Up)
console.log(Direction.Down)
console.log(Direction.Left)
console.log(Direction.Right)
//也可通过下标拿到字符串
console.log(Direction[0])
// 手动赋值
enum Direction1 {
Up = 10,
Down, //Down为11
Left, //Left为13
Right //Right为14
}
enum Direction2 {
Up = 'Up',
Down = 'Down', //Down为11
Left = 'Left', //Left为13
Right = 'Right' //Right为14
}
常量枚举 仅有常量值可以使用常量枚举
const enum Direction2 {
Up = 'Up',
Down = 'Down', //Down为11
Left = 'Left', //Left为13
Right = 'Right' //Right为14
}
8、泛型
//泛型<> T相当于占位符,可以更改。使用的时候指定类型即可
function echo<T>(arg: T): T {{
return arg
}}
const val:string = 'str'
let res1 = echo(val)
//也可以根据类型推断直接传值
let res2 = echo(123)
function swqp<T,u>(tuple:[T,u]): [u,T]{
return [tuple[1] , tuple[0]]
}
约束泛型
在函数内部,由于不清楚函数类型某些方法无法使用,可以通过对泛型做出约束解决
//解决方案 只允许包含length属性的值传入
interface IWithLength {
length: number
}
function echoWithArr<T extends IWithLength>(arg: T): T {
console.log(arg.length) //errror,不清楚arg类型,无法使用length
return arg
}
泛型在类和接口中的使用
//泛型在类和接口中的使用
class Queue <T>{
private data = []
push(item: T){
return this.data.push(item)
}
}
const queue = new Queue<number>() //希望传入的是number类型
interface IKeyPair<T,U> {
key: T,
val: U
}
let kp1:IKeyPair<number,string> = {
key:1,
val:'str'
}
9、类型别名、字面量和交叉类型
//类型别名
type PlusType = (x:number,y:number)=> number
let sum2:PlusType
const res = sum2(2,3)
//字面量 可以限制常量范围
const number:1 = 1
type Directions = 'up' | 'dowm'
let toWhere: Directions = 'up'
//交叉类型
interface IName {
name: string
}
type IPerson = IName & {
age:number
}
let person:IPerson = {
name:'hu',
age: 11
}
10、声明文件
//声明文件 告诉tsc变量已定义,无需报错
//仅仅用于编译时的检查,并非真实定义
declare var jquery:(selector: string) =>any;
鉴于项目存在的ts声明文件可能很多,可以使用插件实现
第二章:报错合集
1、Object is possibly 'null' 应当加非空断言