目录
TS 概念
- 以JavaScript为基础构建的语言
- 一个JavaScript的超集
- 可以在任何支持JavaScript的平台中执行
- TypeScript扩展了JavaScript并添加了类型
- TS不能被JS解析器直接执行
TS 基本类型
常用的数据类型
类型 | 例子 | 描述 |
number | 1,-33,2.5 | 任意数字 |
string | ‘h1’,”h2”,h1 | 任意字符串 |
boolean | true,false | 布尔值true或false |
字面量 | 其本身 | 限制变量的值就是该字面量的值(常量) |
any | * | 任意类型 |
unknown | * | 类型安全的any |
void | 空值(undefined) | 没有值(或undefined) |
never | 没有值 | 不能是任何值 |
object | {name:’xxx’} | 任意的JS对象 |
array | [1,2,3] | 任意的JS数组 |
tuple | [4,5] | 元素,TS新增类型,固定长度数组 |
enum | enum(A,B) | 枚举,TS新增类型 |
| | number | string | 联合类型 |
类型声明
①类型声明式TS非常重要的一个特点
②通过类型声明可以指定TS中变量(参数、形参)的类型
③指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
④语法:
let 变量:类型; let 变量:类型 = 值; function fn(参数:类型,参数:类型): 类型{ …… } |
自动类型判断
TS拥有自动的类型判断机制
当对变量的声明和赋值时同时进行的,TS编译器会自动判断变量的类型
所以如果你的变量的声明和赋值时同时进行的,可以省略掉类型声明
数据类型示例与说明
①number
例如: let a: number; //声明一个变量a,同时指定它的类型为number
② string
例如: let b: string; //声明一个变量b,同时指定它的类型为string
③ |
例如: let c1: 0 | 1; //声明 一个变量c1,同时指定它的值为0或者1
例如:let c2 : number | string //声明一个变量c2,同时指定它的类型为数字或者字符串类型
④ boolean
例如: let d : boolean //声明一个变量d, 同时指定它的类型为布尔类型
⑤字面量
例如: let e = 1 // typeScript在进行变量赋值后,会通过值来判断变量的类型,因此e的变量为number
⑥ any
任意类型,它可以赋值为任意类型,相当与传统的JavaScript,默认类型
⑦ unknown
任意类型,它可以赋值为任意类型,与any不同的是,他不能直接赋值给其他变量,需要先进行判断一下类型
//声明变量如果不指定类型,则TS解析器会自动判断变量的类型为any
let d1:any;
d1 = 10;
d1 = 'hello';
d1 = true ;
// unknown 表示未知类型的值
let e: unknown
e = 10;
e = "hello";
e = true;
let s:string;
// d的类型是any,它可以赋值给任意变量
s = d1;
e = 'hello';
// unknown 实际上就是一个类型安全的any
// unknown类型的变量,不能直接值给其他变量
if(typeof e === "string"){
s = e;
}
⑧ void :没有值, 用于函数/方法申明为没有返回值的函数/方法
⑧ never: 无法返回,一般用于手动抛异常函数/方法
⑨ object: 相当于js对象;
例如:
一般情况下,创建的对象时,所有属性都是必选的,在属性名后边加上?表示属性可选的
let b1: {
name: string,
age?: number
};
b1 = {name: '孙悟空'};
// [propName:string]: any 表示任意类型的属性 可以扩展属性
let c3 : {name:string, [propName:string]:any}
c3 = {name: "猪八戒",age:18,gender: '男'}
⑩ array: JS的数组
⑩-① tuple : 元组,申明后固定长度的数组
let n:[string,string];
n = ['hello','abc']
⑩-② enum : 枚举
示例:
enum Gender{
Male = 0 ,
Female = 1
}
let i : {name:string, gender:Gender};
i = {
name: '孙悟空',
gender: Gender.Male
}
TS 面向对象
修饰符
1、public 修饰的属性可以在任意位置访问(修改值) ,是typeScript默认修饰符
2、protected : 受包含的属性,只能在当前类和当前类的子类中使用
3、private: 私有属性,私有属性只能在类内容进行访问
属性
普通属性
例如:
xxx: any
静态属性
在属性前使用static关键字可以定义类属性,
static开头则方法是类方法,可以直接用过类去调用
所有对象共享这个属性值
static xxx: any
readonly 只读属性
readonly xxx: any
构造器
ts 构造器申明constructor([xxx:any,...]),可以通过构造器来声明对象
在实例方法中,this就表示当前的实例
在构造函数中当前对象就是当前新建的那个对象
例如:
class Dog{
name: string;
age: number;
constructor(name:string,age:number){
console.log("构造函数执行了~")
//在实例方法中,this就表示当前的实例
//在构造函数中当前对象就是当前新建的那个对象
this.name = name;
this.age = age;
}
bark(){
alert("汪汪汪")
//在方法中可以通过this来表示当前调用方法的对象
console.log(this.name);
}
}
const dog = new Dog("小黑",4);
属性封装
在TS中设置getter方法和setter的特殊方法,可以当做一个属性值使用,从而修改和获取对象的私有属性。
例如:
(function () {
//定义一个表示人的类
class Person {
private _name: string;
private _age: number;
constructor(name: string, age: number) {
this._name = name;
this._age = age;
}
//TS中设置getter方法的方法
get name() {
return this._name;
}
set age(value: number) {
if (value > 0) {
this._age = value;
}
}
}
const per = new Person("孙悟空", 18);
console.log(per.name);
per.age = 10
})();
继承
继承可以解决代码,让我们的编程更加靠近人类思维,当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义属性和方法,只需要通过extends来声明继承父类即可。
例如:
(function(){
class Animal{
name: string;
age: number;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
sayHello(){
console.log("动物在叫!");
}
}
//定义一个表示狗的类
// 此时,Animal被称为父类,Dog被称为子类
// 使用继承后,子类将会拥有父类所有的方法和属性
// 通过继承可以将多个类中共有代码写在一个父类中
// 这样只需要写一次即可让所有子类都同时拥有父类中的属性
// 增加一些需求
// 如果在子类中子类中添加了和父类相同的方法,则子类方法会覆盖掉父类方法
class Dog extends Animal{
sayHello(): void {
console.log("汪汪汪汪!")
}
}
//定义一个表示猫的类
class Cat extends Animal{
sayHello(): void {
console.log("喵喵喵喵!")
}
}
const dog = new Dog('旺财',5);
console.log(dog);
dog.sayHello();
const cat = new Cat("咪咪",3);
console.log(cat);
cat.sayHello();
})();
super()
super 代表父类的引用,用于访问父类的属性,方法、构造器
子类构造器必须调用父类的构造器
例如:
(function(){
class Animal{
name: string;
constructor(name: string){
this.name = name;
}
sayHello(){
console.log("动物在叫~");
}
}
class Dog extends Animal{
//子类的构造函数中必须调用父类的super()构造器方法
sayHello(){
// 在类的方法中,super就表示当前类的父类
super.sayHello();
}
}
const dog = new Dog("旺财!");
dog.sayHello();
})();
抽象类
当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类
当父类的一些方法不能确定时,可以用abstract关键字来修饰符该方法,这个方法就是抽象,这个就是抽象方法,用abstract来修饰类就是抽象类。
同时,子类必须重写抽象方法。
例如:
(function(){
// 以abstract开头的类是抽象类
// 抽象类和其他类区别不大,只是不能用来创建对象
// 抽象类就是专门用来被继承的类
// 抽象类增加抽象方法
abstract class Animal{
name: string;
age: number;
constructor(name: string, age: number){
this.name = name;
this.age = age;
}
//定义一个抽象方法
//抽象方法使用abstract开头,没有方法体
//抽象方法只能定义在抽象类中,子类必须对抽象方法进行重写
abstract sayHello():void;
}
//定义一个表示狗的类
// 此时,Animal被称为父类,Dog被称为子类
// 使用继承后,子类将会拥有父类所有的方法和属性
// 通过继承可以将多个类中共有代码写在一个父类中
// 这样只需要写一次即可让所有子类都同时拥有父类中的属性
// 增加一些需求
// 如果在子类中子类中添加了和父类相同的方法,则子类方法会覆盖掉父类方法
class Dog extends Animal{
sayHello(): void {
console.log("汪汪汪汪!")
}
}
//定义一个表示猫的类
class Cat extends Animal{
sayHello(): void {
console.log("喵喵喵喵!")
}
}
const dog = new Dog('旺财',5);
console.log(dog);
dog.sayHello();
const cat = new Cat("咪咪",3);
console.log(cat);
cat.sayHello();
})
接口
①接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
②同时接口也可以当成类型声明去使用
③接口可以定义类的时候可以限制类的结构
④接口中的所有的属性都不能有实际的值
⑤接口只定义对象的结构,而不考虑实际值
例如:
(function(){
//描述一个对象的类型
type myType = {
name: string;
age: number
};
// 接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
// 同时接口也可以当成类型声明去使用
//接口可以在定义类的时候去限制类的结构
//接口中的所有的属性都不能有实际的值
//接口只定义对象的结构,而不考虑实际值
interface myInterface{
name: string;
age: number;
}
interface myInterface{
gender: string
}
const obj: myInterface = {
name: 'sss',
age: 111,
gender: '男'
}
interface myInter{
name: string;
sayHello():void;
}
//定义类时,可以使类去实现一个接口,
//实现接口就是使类满足接口的需求
class Myclass implements myInter{
name: string;
constructor(name:string){
this.name = name;
}
sayHello(): void {
console.log('大家好!')
}
}
})();
泛型
泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方法的返回值的类型。
在调用有类型的对象时,ts可以自动对类型进行推断出泛型的类型
(function(){
/**
* 在定义函数或是类时,如果遇到类型不明确就可以使用泛型
*
*/
function fn<T>(a:T):T{
return a;
}
//可以直接调用具有泛型的函数
fn(10); //不指定泛型,TS可以自动对类型进行推断
fn<string>("hello"); //指定泛型
function fn2<T,K>(a:T,b:K):T{
console.log(b);
return a;
}
fn2(123,"hello");
})();