TypeScript
不要问为什么要学它。直接开干
安装(不需要本地运行*.ts文件的可以不装)
全局安装typescript:npm i -g typescript
编译:tsc *.ts
注意:使用tsc命令编译ts文件后,会生成一个.js的文件*
vscode配置ts
- 执行
tsc --init生成tsconfig.json配置文件 - 菜单选择:终端=>运行任务=>监视tsconfig.json
ts数据类型
-
布尔类型
boolean -
数字
number -
字符串
string -
数组
arraylet arr:number[] = [1,2,3] 或 let arr:Array<number> = [1,2,3] -
元祖
tuplelet arr:[number,string] = [1,'2'] // 定义几个类型就要初始化几个值,一一对应 -
枚举
enumenum sexType { f=1, m=2 } let a:sexType = sexType.f console.log(a) // 1 enum Types {'undefined'=-1,'null'=2,'success'=0} let e:Types = Types.null console.log(e) // 2注意:
- 如果标识符没有赋值,那么value就是他的索引值;
- 如果其中某一个定义了number类型的value,后续的索引都在这个基础上递增;
-
任意类型
anylet box:any = document.getElementById('box'); box.style.color = 'red'; -
null和undefined -
空
void(一般用于定义方法的返回值)function run():void{} -
never不会出现的类型(包括null、undefined)的子类型let a:never = (()=>{ throw new Error('异常')})()
函数定义
参考:TS之函数详解
- 参数要有类型,可配置默认值,可配置可选参数
- 剩余参数
- 函数要有返回值
- 函数可以重载
// 函数创建和声明的两种方式
// 1.关键字
function fn1(a: string): string {
return ''
}
// 2.函数表达式
let fn2: (a: string) => string = function (a) {
return ''
}
// type
type callback = (a: string) => string;
// interface
interface ICallback {
(a: string): string;
}
let fn3: callback = function (a) { return '' }
let fn4: ICallback = function (a) { return '' }
// 默认参数、可选参数
function getInfo(name: String,isOk:Boolean = false,sex?:String):void {}
// 剩余参数
function getInfo(name: String,...result:String[]):void {}
// 函数重载
function getData(id: String): void {
console.log('方法0:', id);
}
function getData(param: String): void {
console.log('方法一:', param);
}
getData('2'); //如果没有下面的方法则输出: 方法一: 2 反之 方法二: 2 -- undefined
function getData(param: String, id?: String): String {
console.log('方法二:', param, '--', id);
return '2';
}
getData('1'); // 方法二: 1 -- undefined
function getData():void {}
类(构造函数)
继承
function User(name){
this.name =name
}
User.prototype.run=function(){
return this.name+'1234567890'
}
// 1.对象冒充继承。 无法继承原型链上的方法
function Web(name){
User.call(this,name)
}
// 2.原型链继承,无法在初始话的时候传值
function Web(){}
Web.prototype = new User()
// 3. 对象冒充继承+原型链继承,完美解决上面两种问题
function Web(name){
User.call(this,name) // 对象冒充继承
}
Web.prototype = User.prototype
let b = new Web('你好')
// console.log(Web.prototype)
console.log(b.name)
console.log(b.run())
ES6以后的实现
class Person {
// public 共有属性
public love: String = '爱';
// private 只能在当前类里面进行访问
private nick: String;
// protected 保护类型 外部无法访问,子类能访问
protected who: String = '你谁啊';
name: String; // 默认就是 public
constructor(name: String) {
this.name = name;
this.nick = name;
}
gitinfo() {
return `${this.nick}`;
}
}
class Web extends Person {
content: String;
constructor(name: String, content: String) {
super(name);
this.content = content;
}
workSome() {
return `${this.name}${this.content},${this.who}`;
}
// 静态方法,无法访问定义当前类属性。this指向当前这个函数
static work() {
return `${this.name}`;
}
}
const my = new Person('张三');
const some = new Web(my.name, '你去做饭吧');
console.log(some.workSome()); // 张三你去做饭吧,你谁啊
console.log(Web.work()); // Web
declare 声明
- 对第三方类型进行扩展(如Uni)
// / <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}
declare module 'uview-ui'
/* eslint-disable @typescript-eslint/no-explicit-any */
import Jsbridge from './util/flutterBridge'
declare global {
interface Window {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
$flutter: typeof Jsbridge
_aMap: any
spBridge: any
NoCaptcha: any
[key: string]: any
}
// 类型融合,解决对uni的扩展
interface Uni {
$api: any
$util: any
$local: any
}
}
export {}
abstract抽象类(定义标准)
- 抽象类是提供给其他类继承的基类,不能被直接实例化
- 用abstract关键字定义的抽象类中的方法,不需要实现,但是在子类中必须实现
- abstract 关键字只能出现在抽象类中
abstract class Ren {
abstract eat(): any;
}
class Person extends Ren {
constructor(name: String) {
super();
}
// 抽象类的抽象方法必须在子类进行实现,孙子类可以不实现
eat() {
return '吃东西';
}
}
interface接口,定义约束规范
- 接口中的字段以;结尾
- interface 可以约束定义属性对象。但是属性值必须一一对应,不能多字段或者少字段;
属性类型的接口
interface ParamObj {
label: String;
value?: Number;
// name: String = 'interface'; 不能初始化值
}
function printLabel(param: ParamObj) {
console.log('输出:', param.label);
}
printLabel({ label: '你好ts' });
printLabel({ label: '你好ts', value: 2 });
函数类型的接口
- 参数必须由()包裹起来
// 例子:一
interface FnTyoe {
(id: String, type: Number): String;
}
const fn: FnTyoe = function (id: String, type: Number) {
console.log('输出:', type);
return id;
};
fn('你好ts', 2);
// 例子:二
interface ParamObj {
id: String;
type: Number;
}
interface FnObjTyoe {
(param: ParamObj): String;
}
const fn1: FnObjTyoe = function (param: ParamObj) {
console.log('输出:', param.type);
return param.id;
};
fn1({ id: '你好ts', type: 2 });
数组、对象类型的接口
key||index必须由[]包裹起来
// 例子:一
interface StrArr {
[index: number]: String;
}
const arr: StrArr = ['1', '2'];
// const arr: StrArr = ['1', 2]; ❌
console.log(arr);
// 例子:二
const obj: StrArr = { 1: '1' };
// const obj: StrArr = { 1: '1', 2: 2 }; ❌
console.log(obj);
类类型的接口
- 使用关键字
implements - 按照接口规范必须定义相应的
属性和函数
// 例子:一
interface Ren {
name: String;
age?: String;
eat(value: String): void;
}
class Person implements Ren {
name: String; // 必须实现 ✅
sex: String;
constructor(name: string) {
this.name = name;
this.sex = '男';
}
// eat 必须实现 ✅
eat() {
console.log(this.name + '吃吧!');
}
}
const a = new Person('张三');
a.eat();
interface的扩展||继承
- 使用
extends来做继承
// 例子:一
interface Animal {
age: Number;
eat(): void;
}
interface Ren extends Animal {
name: String;
work(): void;
}
class Web {
name: String;
constructor(name: string) {
this.name = name;
}
coding() {
console.log(this.name, '写代码');
}
}
class Person extends Web implements Ren {
name: String; // 必须实现 ✅
sex: String;
age: Number; // 必须实现 ✅
constructor(name: string, age: Number) {
super(name);
this.age = age;
this.name = name;
this.sex = '男';
}
// eat 必须实现 ✅
eat() {
console.log(this.name + '吃吧!');
}
// eat 必须实现 ✅
work() {
console.log(this.name + '好好干');
}
}
const a = new Person('张三', 22);
a.eat();
a.coding();
T泛型(可以不用T用其他也行)
- 定义一个不特定的类型
函数泛型
// 例子:一
function getData<Z>(value: Z): Z {
return value;
}
getData<String>('abc');
// getData<String>(1234567);❌
getData({ key: 111 }); // 不写类型相当于any
类泛型
这里的T代表下面的T都是泛型
// 例子一
class Peron<T> {
arr: T[] = [];
add(value: T) {
this.arr.push(value);
}
getArr(): T[] {
return this.arr;
}
}
const a = new Peron<String>();
a.add('1');
// a.add(12345); ❌ 初始化 const a = new Peron<String | Number>();才能传入数字
const aa = a.getArr();
console.log(aa);
// 例子二
class User {
name: String;
sex: String;
constructor(name: String) {
this.name = name;
this.sex = '男';
}
}
const b = new Peron<User>();
// b.add('111'); ❌
b.add(new User('张三'));
泛型接口interface
// 例子一
interface FnType {
<T>(value: T): T;
}
const fn: FnType = function (value: T): T {
return value;
};
fn<String>('abc');
// fn<String>(12345); ❌
// 例子二
interface FnType1<T> {
(value: T): T;
}
function getData<T>(value: T): T {
return value;
}
const fn1: FnType1<Number> = getData;
// fn1('ddd');❌
fn1(123);
例子二
interface ObjType<T> {
addUser(id: T): Boolean;
getInfo(param: Number): T;
}
class User {
name: String;
age: Number;
constructor(name: String, age: Number) {
this.name = name;
this.age = age;
}
}
class SchoolUser {
name: String;
age: Number;
sex: String;
constructor(name: String, age: Number) {
this.name = name;
this.age = age;
this.sex = '男';
}
}
class School<T> implements ObjType<User> {
name: String;
users: User[];
constructor(name: String) {
this.name = name;
this.users = [];
}
addUser(value: User) {
this.users.push(value);
return true;
}
getInfo(age: Number) {
let result;
this.users.forEach((e: User) => {
if (e.age === age) result = e;
});
return result;
}
update(value: T) {
console.log(value);
return true;
}
}
const a = new School<SchoolUser>('秦岭学校');
const u = new User('张三', 22);
const u1 = new SchoolUser('李四', 23);
a.addUser(u);
// a.update(u); ❌
a.update(u1);
console.log(a.getInfo(22)); // User {name: '张三', age: 22}