基础介绍
语法基础
ts代码执行的过程是先通过编辑器将ts 代码编译成js 代码,然后在浏览器中执行。
- 安装typescript,以及编译
# 全局安装typescript
npm install -g typescript
# 使用tsc命令将ts 脚本编译成js 脚本在浏览器端执行
tsc test.ts -> test.js
- 编写代码过程中发现一个代码提示提示错误
问题: Cannot redeclare block-scoped variable
原因: ts 编译了一份js 源码后,ts和js 中都有相同的一份变量,这个时候编辑器会认为进行了redeclare
解决: 在ts 文件中使用export {} 来表示此文件是一个模块
- 语法思维导图概览
基础代码
变量的基本定义
// 在不指定类型的基本类型中ts 会进行类型推断
let a = 2;
// 函数赋值给变量
let hello = (name:string) => {
return `hello ${name}`;
};
hello("sunboy")
// 定义变量时直接将类型指定明确
let isDone:boolean = false;
let age:number = 10;
// 数组 限定数据类型
let arrOfNumbers:number[] = [1, 2, 3, 4, 5];
let newArrayOfNumbers = arrOfNumbers.concat([33,34,56],[12,13,14])
arrOfNumbers.push(3);
console.log(newArrayOfNumbers, arrOfNumbers);
// 元组 类似python中的列表,可以由多种数据类型组成
let user:[string,number] = ['sunbing',12];
user.push('12')
user.push(34)
user.pop();
console.log(user)
interface 接口的使用, 接口用来描述对象的形状, 接口中的属性设置也非常的灵活好用, 只读属性,可选属性都可以在构造对象的时候来使用,同时也能用来申明类型
// interface 接口 非常灵活
// 申明一个Person 接口
interface Person {
readonly id:number; // 只读属性 const 用在变量只读不可改
name:string;
age:number;
sex:string;
country?:string; // 可选类型
}
// 在构造对象的时候要对比实现接口中国的属性
let sunboy:Person = {
id:2,
name: 'sunboy',
age: 34,
sex: 'male'
}
// 当然我们的函数类型的可选参数也能使用 参数名? 的形式来使用
// 下面的函数就是来使用可选参数达到不同的计算目的
const add = (x:number, y:number,z?:number) : number => {
if(typeof z === 'number') return x + y + z;
return x + y;
}
// 使用接口来申明一个函数类型
interface ISum{
(x:number, y:number, z?:number):number
}
// 将函数赋值给另外一个变量
let add2:ISum = add;
联合类型+类型断言+类型守护 类型断言 和 类型守护,本质上都是对类型的一种判断筛选
// 联合类型 定义一个变量可能是多种类型中的一种 ,并且只能访问公共的方法
let name: number | string;
// 联合类型+类型断言来判断 输入参数 获取参数长度; as 用来做断言
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;
}
}
console.log(getLength(11))
console.log(getLength('我是谁'))
// type guard 类型守护
function getLength2(input: string | number): number {
if (typeof input === 'string') {
return str.length;
}
return input.toString().length;
}
console.log(getLength2('我是谁'))
面向对象 封装、继承、多态
// 封装一个父类
class Animal {
// 成员变量
name:string;
constructor(name: string){
this.name = name;
}
run(){
return `${this.name} is running`
}
}
// 狗类继承 Animal 类
class Dog extends Animal {
// 子类方法
break(){
return `${this.name} is breaking`;
}
}
//cat 中对run方法进行重写,子类体现对于父类的不同形态
class Cat extends Animal {
readonly legs = 4;
static catefories = ['mammal'] // 静态属性 类调用
constructor(name: string){
super(name); // 重写
console.log(this.name)
}
run() {
return ' Meow ' + super.run();
}
}
const snake = new Animal("lizard");
console.log(snake.run());
const dog = new Dog('didi');
console.log(dog.break());
const cat = new Cat('xiaohei');
console.log(cat.run());
/*
*类和接口
车 和手机都有开收音机的功能
但是车和手机不太好抽象一个类出来,这个时候,可以抽象出一个Radio 接口出来,
然后在类去实现(implements)它,同样的的接口也可以继承接口。
鸭子类型: 长得像鸭子就是鸭子
*/
interface Radio{
// 申明方法
switchRadio(trigger:boolean):void;
}
interface Battery{
checkBatteryStatus():void;
}
interface RadioWithBattery extends Radio{
checkBatteryStatus():void;
}
class Car implements Radio {
switchRadio(trigger:boolean){
}
}
class CellPhone implements RadioWithBattery {
switchRadio(trigger:boolean){
}
checkBatteryStatus(){
}
}
枚举类型: 组织、收集变量的形式
/**
* 枚举类型
*
*/
const enum Direction {
Up,
Left,
Right,
Down,
}
console.log(Direction.Down)
泛型 T: 可以当作是一种类型的占位符,使用时候动态填入类型 泛型解决在函数或者变量定义的时候不指定类型在使用的时候指定
// 申明一个函数,参数类型为泛型
function echo<T>(value: T):T{
return value
}
// 此时参数类型为number类型
const result = echo(123)
console.log(result)
// 泛型实现元组元素互换
function swap<T, X>(tuple: [T, X]):[X, T] {
return [tuple[1],tuple[0]]
}
const result2 = swap([123,'string'])
console.log(result2);
// 泛型类型的数组
function echoWirhArr<T>(arg:T[]):T[]{
console.log(arg.length);
return arg;
}
const arrs = echoWirhArr([1,2,3,4,5])
console.log(arrs);
// 上面的代码中,只能参数是数组的可以使用。
//不过我们有更好的实现方式,使用接口来实现,只要含有length 属性就可以使用
interface IwithLength{
length: number;
}
function echoWirhArLength<T extends IwithLength>(arg:T ) : T {
console.log(arg.length);
return arg;
}
const newArrs = echoWirhArLength("syung");
const newArrsDuch = echoWirhArLength({length: 13,width:24});
console.log(newArrsDuch)
console.log(newArrs);
/*
泛型在类中的使用
*/
// 申明一个队列
class Queue<T> {
private data = [];
push(item: T) {
return this.data.push(item);
}
pop(): T {
return this.data.shift();
}
}
// 在申明队列的时候可以指定任何类型的对了
const queue = new Queue<number>()
queue.push(1)
queue.push(2)
console.log(queue.pop().toFixed());
console.log(queue.pop().toFixed());
// interface 搭配 泛型 使用, 参数类型更加的自由
interface KeyValue<T,U>{
key:T,
value:U
}
// KeyValue , Array 都属于interface,在编辑器中悬浮在上面可以看到它的类型
let p:KeyValue<number,string> = {key:1,value:"test1"}
let p2:KeyValue<string,number> = {key:"1",value:2}
let a1:Array<number> = [1,2,3,4]
let a2:number[] = [1,2,3,4]
类型别名+字面量+交叉类型+文件申明
// 类型别名 就是给类型起一个名字,类似快捷键 使用type 关键字
// 申明一个类型
let sumTwoNumber: (x:number, y:number) => number;
const s1 = sumTwoNumber(1,2);
type PlusType = (x:number, y:number) => number;
let sum2: PlusType
const r2 = sum2(3,4)
// 在类型别名中可以使用联合类型
type StrOrNumber = string | Number
let r3:StrOrNumber = "123"
let r4:StrOrNumber = 123
// 字面量 是js 提供的准确变量
const str:'name' = 'name'
const number:1 = 1
type CarbinDirection = 'Up' | 'Down' | 'Left' | 'Right'
let toThere:CarbinDirection = 'Down'
// 交叉类型 使用 & 符号进行连接
interface IName{
name: string
}
type IPerson = IName & {
age:number
}
let person1:IPerson = {name: 'John', age:23}
console.log(person1)
// 文件申明 , ts 有个 types 的库 对很多的js 的第三方进行了文件的declare 申明
// 一般对于第三方库不自己申明 官方库有提供需要可以npm install 包名即可
https://github.com/DefinitelyTyped/DefinitelyTyped
vue3 开发环境配置
vue-cli 创建项目
# 1、创建项目
vue create vue-basic
# 2、选择vue 项目的模版 以及它的格式检查工具,见下图。
选择最后手动选择特性,回车选择vue3,然后一路火花带闪电回车到底也可以(主要是babel 、 ESLint选好可以)
# 3、等待一会儿出现Successfully created project vue-basic. 证明项目已经创建好了
使用vite 创建vue 项目
npm create vite@latest
# Project name: 输入项目名称
# Select a framework: vue
# Select a variant: vue-ts
cd project-name
npm install
npm run dev
针不戳