TypeScript
- 学习网址:https://24kcs.github.io/vue3_study/chapter3/01_%E8%AE%A4%E8%AF%86Vue3.html#_3-%E6%96%B0%E5%A2%9E%E7%89%B9%E6%80%A7
安装
-
npm install typescript -g
-
安装完成后,在控制台运行如下命令,检查安装是否成功(3.x):
-
tsc -V
-
使用
接口案例
(()=>{
interface Person{
firstName:String,
lastName:String
}
function fun(person:Person){
return person.firstName +","+ person.lastName
}
const per = {
firstName:"Jarry",
lastName:"Zip"
}
console.log(fun(per))
})()
类 案例
(()=>{
// 定义一个类
class Person{
name:String
age:number
// 构造器
constructor(name:String,age:number){
this.name = name
this.age = age
}
}
const per = new Person("Jarry",33)
console.log(per.name+','+per.age)
})()
数组类型
- 注意:数组定义后,里面的数据的类型必须和定义数组时候的类型是一致的
-
定义方式1
- 语法:
let 变量名:数据类型[] = [值1,值2]
let arr1 : number[] = [3,6,6];
- 语法:
-
定义方式2(泛型写法)
- 语法:
let 变量名:Array<数据类型> = [值1,值2]
let arr2 : Array<number> = [4,5,6]
- 语法:
-
元组类型
-
在定义数组的时候,类型和数据的个数一开始就已经限定了
let arr3 : [string,number,boolean] = ['Jarry',100,true]
- 注意:数据类型的位置要和数据元素的类型保持一致
-
枚举 类型
-
枚举类型 里面的每个元素都有自己的编号,编号是从0开始的,依次递增1
-
但是也可自己指定,其后的元素依次递增(详看案例2)
-
案例1
enum Color{ red, green, blue } let result:Color = Color.red console.log(result,green,blue); // 0,1,2
-
案例2(指定值)
enum Color{ red = 1, green, blue, } let result:Color = Color.red; console.log(result,green,blue); // 1,2,3 console.log(Color[3]); // blue 【索引从1开始计算】
-
案例3(其中的元素也可为中文,但是不推荐)
enum Person{ 女, 男 } console.log(Person.男); // 1
-
Any 类型
-
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型.这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。这种情况下, 我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。那么我们可以使用any 类型来标记这些变量:
let str:any = 100; console.log(str); // 100 let str1:any = "Jarry"; console.log(str1); // Jarry // 当一个数组中要存储多个数据,个数不确定,类型不确定,此时便可以用 any 类型 let arr : any[] = [100,"Jarry",true]; console.log(arr); // [100,Jarry,true]
void 类型
-
某种程度上,
void 类型
与any类型
相反,它表示没有任何类型
。当一个函数没有返回值时,通常会见到其返回值类型是 voidfunction fun():void{ console.log("This is void function!") } console.log(fun()); // undefined
object
-
object 表示非原始类型,也就是除
number
,string
,boolean
之外的类型 -
使用
object
类型,就可以更好的表示像object.create
这样的API
function getObj(obj:object) : object { console.log(obj) return { name:"Jarry", age:45 } } console.log(getObj({name:"Zip",age:45})); // {name:"Zip",age:45} {name:"Jarry",age:45} console.log(getObj(new String("234"))); // String {"234"} {name:"Jarry",age:45} console.log(getObj(String)); // String () {name:"Jarry",age:45}
联合类型、类型断言
-
表示可以为多种类型中的一个,
|
代表或-
案例1 :定义一个函数得到一个
数字
或字符串
的字符串
形式值function fun(str : number | string) : string { return str.toString() } console.log(fun(123)); // 123 console.log(fun('123')); // 123
-
案例2:定义一个函数得到一个
数字
或字符串
的长度- 类型断言:告诉编译器,开发者知道什么类型的数据,在编译阶段先忽略这个错误,但是不影响运行阶段
- 类型断言使用方式 1:
<类型>变量名
- 类型断言使用方式 2:
值 as 类型
function getString(str : number | string) : number { // return str.toString().length // 改进:【类型断言】 (如果传入的是字符串类型的值,就不需要再转化为字符串了,所以需要改进) // 如果str.length 存在,说明 str 是String 类型 if( (<string>str).length){ // 如果str 是数字类型,那么判断str.length 时就会报错,因为只有字符串才能获取其长度;为了解决这个问题,要用 “ 类型断言 ” return (str as string).length }else{ return str.toString().length } } console.log(getString(123321)) // 6 console.log(getSting('Hello')) // 5
-
类型推断
-
TS 会在没有明确的指定类型的时候推测出一个类型
let txt = 100; console.log(txt); // 100
接口
-
约束该对象中的属性数据
readonly
只读属性 (类似于Java中的private
修饰符)?
表示可以不存在的属性
-
-
在接口中定义变量
interface Person{ // id 是只读的,是number类型 readonly id:number name:string age:number // 可有可无属性 sex?:string } const person:Person = { id:1, name:"Jarry", age:45, // 因为 sex 可以不存在,所以在这里可以不写此数值 sex:'女' } // person.id = 233 不能在这里赋值,因为id是只读属性
-
在接口中定义某个函数
- 要使用接口表示函数类型,首先要给接口定义一个调用签名(只有一个参数列表和返回值类型的定义)
// 接口 interface isFun{ (str1:string,str2:string) : boolean } // 函数类型 const fun : isFun = function (str1:string,str2:string) : boolean { return str1 == str2 } console.log(fun("jarry","jarry")) // true
-
类
-
类实现接口
-
只有在类中使用才可以在接口中写此格式方法,以上未在类中定义,所以书写格式不一样;
- Java 中都是类与类的关系
-
一个类可以实现多个接口
-
Java
: Java 的接口中定义一个方法(函数)时,也不能写其具体方法,而且只能是抽象- 语法:
public abstract void show()
或void show()
- 语法:
interface IFlyA{ fly() } interface RunB { run() } // 一个类可以调用多个接口( Java 等同) class Person implements IFlyA , RunB { fly(){ console.log("I can flying!") } } const per = new Person() per.fly() // I can flying! per.fun()
-
-
一个接口也可继承其它多个接口 (Java 等同)
interface inter1 { eat() } interface inter2 { show() } interface interSum extends inter2 , inter2 { play() } class Person implements interSum { eat(){console.log("The man is eating!")} play(){console.log("The man is playing!")} show(){console.log("The man is showing!")} } const per = new Person() per.eat() per.play() per.show()
-
类的继承
class Person { name:string age:number constructor(name:string,age:number){ this.name = name; this.age = age } fun(){ console.log(`${this.name}调用了Person父类的方法`) } } class Man extends Person{ sex:string constructor(sex:string,name:string,age:number){ super(name,age) this.sex = sex } fun(){ console.log(`${this.name}调用了Man子类的方法,He is a ${this.sex}`); super.fun() } } const man1:Man = new Man("boy","Jarry",14) man1.fun() // Jarry调用了Man子类的方法,He is a boy <br/> Jarry调用了Person父类的方法
多态
-
父类型的引用指向了子类型的对象,不同类型的对象针对相同的对象,产生了不同的行为
class Person{ name:string constructor(name:string){ this.name = name } eat(){ console.log("The Person is eating"); } } class Woman extends Person{ constructor(name:string){ super(name) } // 重写父类的方法 eat(){ console.log("The Woman is eating!") } show(){ console.log("The woman is showing!"); } } const woman1:Person = new Woman("Jarry"); woman1.eat() // The Woman is eating! // woman1.show() 只能调用父类中已申明的方法 ; 没有在父类中申明(定义),不能被调用 const woman2:Person = new Woman("black"); woman2.eat() // The Woman is eating! function fun(str:Person){ str.eat() } fun(woman2) // The Woman is eating! fun(woman1) // The Woman is eating!
修饰符 (用法和 Java 相同)
-
主要是描述类中的成员(属性,构造函数,方法)的可访问性
- **public ** :类中成员的默认修饰符,公共的,任何位置都能访问
- private :外部是无法访问这个成员的,子类也是无法访问该成员
- protected : 外部无法访问,但是子类可以
class Person{ private name:string public name:string protected name:string }
函数重载
// 函数重载声明 function add(x: string,y: string): string function add(x: number,y: number): number // 函数声明 function add(x: string | number,y: string | number): string | number { if(typeof x === 'string' && typeof === 'string'){ return x + y; // 字符串拼接 }else if(typeof x === 'number' && typeof y === 'number'){ return x + y; // 数字相加 } } // 函数调用 console.log(add('Jarry','Zip')) console.log(add('Jarry',19)); // 传入的时非法数据,报错
泛型
-
在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定具体类型的一种特性
function getArray<T> (value: T,count: number): T[] { // 根据数据和数量产生一个数组 // const arr: T[] = [] const arr:Array<T>=[] for(let i = 0;i < count; i++){ arr.push(value) } return arr } const arr2 = getArray<number>(100,5); const arr1 = getArray<string>("abc",4);
-
多个泛型参数的函数
(()=>{ function getMsg<K,V>(value: K,value2: V): [K,V] { return [value,value2] } const arr1 = getMsg<string,number>('Jarry',100.3444) console.log(arr1[0]); console.log(arr1[1].toFixed(1)) // 保留一位小数 })()
-
泛型类
(()=>{ // 定义一个泛型类 class Person<T>{ defaultValue:1 add:(x: T,y: T) => T } // 实例化类的对象 const p1: Person<number> = new Person<number>() // 设置属性值 p1.defaultValue = 100 p1.add = function (x, y) { return x + y; } console.log(g1.add(10, 20)) // 30 })()