当前位置: 首页 > news >正文

东营网站建设哪家好/石家庄百度seo排名

东营网站建设哪家好,石家庄百度seo排名,徐水住房建设局网站,山东专业网站建设公司哪家好文章目录 一、类型1、定义类型2、any、unknown、never3、基础类型4、联合类型5、交叉类型6、type、typeof7、作用域 二、数据结构1、数组2、元组3、函数类型4、对象类型 三、接口四、泛型五、enum六、断言七、工具1、模块2、namespace3、装饰器4、declare5、运算符6、映射类型7…

文章目录

  • 一、类型
    • 1、定义类型
    • 2、any、unknown、never
    • 3、基础类型
    • 4、联合类型
    • 5、交叉类型
    • 6、type、typeof
    • 7、作用域
  • 二、数据结构
    • 1、数组
    • 2、元组
    • 3、函数类型
    • 4、对象类型
  • 三、接口
  • 四、泛型
  • 五、enum
  • 六、断言
  • 七、工具
    • 1、模块
    • 2、namespace
    • 3、装饰器
    • 4、declare
    • 5、运算符
    • 6、映射类型
    • 7、类型工具
    • 8、语法注释
    • 9、tsconfig.json

TypeScript 可以看成是 JavaScript 的超集(superset),即它继承了后者的全部语法,添加了一个独立的类型系统

一、类型

1、定义类型

  • js的类型是动态的,变量定义以后,可以赋值另一个类型的值,这导致了不确定性;
// 报错
// 不能将类型“number”分配给类型“string”。
let bar:string = 123;// 类型推断为string; 鼠标放在sayHello函数上,查看函数定义,可以看到
// 返回值类型被推断; 
// (local function) sayHello(name: string | number): string
function sayHello(name:string | number){return name + "";
}
sayHello('zhangsan')

2、any、unknown、never

// any类型
// 加了any类型,感觉是回到了js,当然一般的项目会限制使用any类型
let anyVar: any = 123;
let anyVarUndefined: any;anyVar = "hello world";
let anyVarbar = anyVar;
console.log(anyVar); // 输出hello world
console.log(anyVarUndefined); //不会报错,any类型可以赋值undefined
console.log(anyVarbar + 123); // any类型变量赋值给其他变量,会导致其他变量也变成any类型// 不给变量定义类型,那么等于any类型
// (local function) getNumber(count1: any, count2: any): any
function getNumber(count1, count2){return count1 + count2;
}
// unknown
// 类型感觉只是对值的类型规定,而不能再后续正常使用
let num: unknown = 1;
num = num + 1; // 报错:“num”的类型为“未知”。
// 在判断中限制unknown的类型为具体类型,就可以使用了
if(typeof num === 'number'){num = num + 1
}
// never类型
let neverVar: never;
// 空类型,不能在任何地方使用
neverVar = neverVar + 1; // 报错:不能将类型“number”分配给类型“never”。
// 一般用于函数永不返回的情况,比如抛出异常
function f(): never {throw new Error('Error');// 注意当你返回值类型为never,依旧return语句会报错// 需要使用as 类型推定return undefined as never;
}
// never 是其他类型子集,所以可以赋值给其他类型
// never是底层类型,在这之上可以再次定义类型
let v1:number = f(); // 不报错
let v2:string = f(); // 不报错

3、基础类型

// 基础类型
// string\number\boolean\null\undefined\symbol
let str:string = "hello world";
let num1:number = 123;
let bool:boolean = true;
let nullVar:null = null;
let undefinedVar:undefined = undefined;
let symbolVar:symbol = Symbol();// 对象类型
const x:object = { foo: 123 };
const y:object = [1, 2, 3];
const z:object = (n:number) => n + 1;// 包装类型
// 大写String包含两种:一个是字面量类型,一个是对象类型;
// 小写string只有字面量类型
const s1:String = 'hello'; // 正确
const s2:String = new String('hello'); // 正确
const s3:string = 'hello'; // 正确
const s4:string = new String('hello'); // 错误,不能将类型“String”分配给类型“string”。// 大写Object,除了null和undefined外,Object包含其他所有类型
let obj:Object;
obj = true;
obj = 'hi';
// 小写object只有引用数据类型
let obj1:object;
obj1 = [];// 值类型
// ts中任何变量都是有类型的,注意很多时候被默认推导了
// let 会给 strValue1 推导类型为 string
let strValue1 = 'hello';
// const 会给 strValue2 推导类型为 hello (普通类型的值)
const strValue2 = 'hello';
// const 会给 objValue 推导类型为 object (引用数据的值)
const objValue: object = { foo: 1 };
// 注意:引用数据会被推导
//   const objValueNoType: {
//     foo: number;
// }
const objValueNoType = { foo: 1 };// 主动设置值类型(单个值)
let numValue1: 1 = 123; // 不能将类型“123”分配给类型“1”。
let numValue2: 123 = 123; // 不能将类型“123”分配给类型“1”。
let numValue3: number = 123;
// 注意 number 类型 包含 123 类型
numValue2 = numValue3; // 错误:不能将类型“number”分配给类型“123”。
numValue3 = numValue2; // 正确

4、联合类型

// 联合类型
// 多个类型组合在一起的类型,可以是不同类型的值,也可以是同一类型的值
// 可以给变量增加类型 null | undefined
let unionValue1: string | number | null | undefined = 123;
let unionValue2: 'hello' | 'world' | number = 'hello';
// 联合类型可以被看成是 类型范围的扩大
// 使用的时候需要类型缩小,否则会报错;也就是说类型范围的变化不会减少工作量
if(typeof unionValue1 === 'number'){console.log(unionValue1.toFixed(2));
}

5、交叉类型

// 交叉类型
// let intersectionValue1: number | "hello"
// string类型包含hello类型,交叉类型就是'hello'类型
// 最终交叉类型依旧是联合类型:number | "hello"
let intersectionValue1: (string | number) & (number | boolean | 'hello') = 'hello';

6、type、typeof

// type 类型别名
// 给一个类型起一个别名,方便使用;类型可以是一个变量
// ts增加了类型系统,那么需要搭配类型变量,更加灵活使用
type MyType = string | number | boolean;
let myVar: MyType = true;// typeof
// typeof 在js里返回最终值的类型
// typeof 在ts里获取类型,两者是不一样的
console.log('typeof myVar', typeof myVar); // boolean js中的 typeof 运算符
let myTypeofVar1: MyType;
// 使用其他变量的类型
// let myTypeofVar2: MyType
let myTypeofVar2: typeof myTypeofVar1 = true;

7、作用域

// 类型变量具有作用域
try {type MyType = string | number;
} catch (error) {type MyType = boolean;
}

二、数据结构

1、数组

// 数组类型
// 规定了数组中每个元素的类型,但不规定元素的个数
// 成员数组类型
// number[] 等价于 (number)[]
let arr0: number[] = [1, 2, 3];
let arr1: (string | number)[] = [1, 2, '3'];
// 泛型数组类型
let arr2: Array<string | number> = [1, 2, '3'];// 获取数组类型其中的一个元素类型
type Names = (string | number)[];
type Name = Names[0]; // string | number
type Name1 = typeof arr1[0]; // string | number
// 注意类型数据不能打印出来,只能在编译期间使用
// console.log('数组类型', Name); // 报错// 数组类型推断
// 自动推断为:let arr3: (string | number)[] (前面讲过,默认是any类型)
let arr3 = [1, 2, '3'];
// arr3.push(true); // 推断过一次,不会继续推断;类型不对会报错// 只读数组
// 数组的元素不能被修改,只能读取
let readonlyArr1: readonly string[] = ['hello', 'world'];// readonly string[] 相当于简化版,没有push、pop等属性
// 所以readonly string[] 是父类型,string[]是他的子类型,子类型添加了更多方法
arr3 = readonlyArr1; // 错误:父类型不能赋值给子类型
readonlyArr1 = ['hello', 'world']; // 正确
// 简单说,属性多\功能全的类型可以赋值给属性少的类型(如果他们有父子关系),但是反过来不行// 另外三种只读数组
// ReadonlyArray\Readonly\const
const a1:ReadonlyArray<number> = [0, 1];const a2:Readonly<number[]> = [0, 1];const arr = [0, 1] as const;// 多维度数组;
// 从左往右读取,最左边是数组最深层的元素,最右边是数组最外层的元素
const arr4: string[][] = [['hello', 'world'], ['foo', 'bar']];

2、元组

// 元组类型
// 规定了数组中每个元素的类型,且元素的个数也做规定;可选元素可以用?表示,只能放在最后面
let tuple1: [string, number?] = ['hello', 123];
// ... 扩展运算符可以增加无限多个元素
let tuple2: [string, ...number[],] = ['hello'];
// 元组中元素的名称, 没有实际意义,只是语义化的作用
let tuple3: [message: string, count: number] = ['hello', 123];
// 获取元组类型的元素类型,通过数字索引
type TupleType = [string, number?];
// 注意类型变量也只能赋值给类型变量;不能当成值变量使用
type TupleType1 = TupleType[1]; // number | undefined
// const tuple4 = TupleType[0]; // 报错// 只读元组
// readonly 关键词;或者使用泛型 Readonly<[string, number]>
let readonlyTuple1: readonly [string, number] = ['hello', 123];
let readonlyTuple2: Readonly<[string, number]>  = ['hello', 123];// 元组长度length
let tupleLength1: [string, number] = ['hello', 123];
let tupleLength2: [string, number, boolean?] = ['hello', 123, true];
let tupleLength3: [string, ...number[], ] = ['hello', 123, ];
// 当元组长度固定,length属性为定值,使用其他值会报错
// if(tupleLength1.length === 3){ // 报错
//     console.log('tupleLength1.length', tupleLength1.length);
// }
// 当元组长度固定几个选项 1、2、3
if(tupleLength2.length === 3){console.log('tupleLength2.length', tupleLength2.length);
}
// 当元组长度不固定,可以随意判断长度
if(tupleLength3.length === 3){console.log('tupleLength2.length', tupleLength3.length);
}// 元组在函数参数中使用
// 注意函数参数一般有固定的元素数量,这个时候使用元组确定数量
function tupleSayHello(name:string, age:number):void{console.log(`hello ${name}, your age is ${age}`);
}
const tupleArr1: [string, number] = ['hello', 123];
const tupleArr2 = ['hello', 123]; // (string | number)[] 会被认为数量无限
tupleSayHello(...tupleArr1); // 正确
// sayHello(...tupleArr2); // 报错 sayHello只接受有限的2个参数const tupleArr3 = ['hello', 123] as [string, number]; // 推断类型
// 只读的值数组,可以用as const来定义成元组类型
const tupleArr4 = ['hello', 123] as const;
tupleSayHello(...tupleArr4)

3、函数类型

// 函数类型
// 默认是有返回值类型推断的,可以省略(除非条件不充足,无法推断)
type funType = (x: number, y: number) => void;
// 方式1;注意不写参数类型会被推断为any类型
const funAdd1 = (x: number, y: number, z) => x + y;
// 方式2
const funAdd2: (x: number, y: number) => number = (x, y) => x + y;// 参数数量
let funAdd3: (x: number, y: number) => number = (x, y) => x + y;
funAdd3 = (x: number) => x + 1; // 正确;可以少于初始化定义的参数数量
// funAdd3 = (x: number, y: number, z: number) => x + y + z; // 错误:参数大于定义的数量// keyof 关键字获取函数的类型(注意得到的是type名)
const funAdd4: funType = (x: number, y: number) => x + y; // 正确
// keyof 关键字获取函数的类型(注意得到的是类型)
// const funAdd4 = (x: number, y: number) => x + y; // 正确
const funAdd5: typeof funAdd4 = (x, y) => x + y; // 正确;// 对象方式定义函数类型
let fooObj: {(x:number): void;
} = (x) => {return x + 1;
};
// 等同于
interface FooObj {(x:number): void;
}
let fooObj1: FooObj = (x) => {return x + 1;
};// 特殊类型 Function
let fooObj2 = (cb: Function, x: number) => {return cb(x + 1);
};// 箭头函数; 注意ts中参数区域要用括号包裹起来;返回值写在括号后面
const funAdd6 = (x: number): number => x;// 参数可选; 注意 y的类型是 number | undefined
// 可选的?的位置只能在最后面追加参数;前面的参数想要使用undefined得单独加
// void 返回值表示不能使用 return 返回内容
const funAdd7 = (x: number | undefined = 0, y?: number): number => {// 注意在代码中写的typeof是值的类型判断,而不是类型变量if(typeof x === 'number' &&  y !== undefined){return x + y;}x?.toFixed(2); // 注意?.运算符,可以安全的使用undefinedy?.toFixed(2);// 如果不判断就使用x、y,会报错// return x + y// 注意必须有默认值,因为定义了返回值return 0;
};
funAdd7(undefined); // 正确
funAdd7(1); // 正确
funAdd7(1, undefined); // 正确
funAdd7(1, 2); // 正确
funAdd7(undefined, 2); // 正确// 函数参数默认值
// 不可以可选时使用默认值:y?: number = 0
const funAdd8 = (x: number = 0, y: number = 0) => x + y;
// undefined 不会覆盖默认值
funAdd8(undefined); // 0// 参数结构
type FunTypeAdd9 = {x: number, y: number}
const funAdd9 = ({ x, y }: FunTypeAdd9) => x + y;
funAdd9({ x: 1, y: 2 }); // 3// rest参数
// 剩余参数,可以接收任意数量的参数,会被存入一个数组中
// args 这个名字可以自定义, 但是必须放在最后面
const funAdd10 = (type: string, ...args: number[]) => {let sum = 0;for(let i = 0; i < args.length; i++){sum += args[i];}return sum;
};
funAdd10('add', 1, 2, 3); // 6// readonly 关键字
// const funAdd11 = (x: readonly number[], y: number) => x[0]++;
// funAdd11( [1, 2, 3], 1); // 错误:不能修改只读数组// void 关键字
// 一般用于函数没有返回值,或者返回值没有意义的情况
const funAdd12 = (x: number): void => {// 没有return,或者return undefined || null// 或者 throw new Error('something wrong');// 当然函数默认返回的就是undefined// return 1; // 错误// return ''; // 错误return; // 正确return undefined; // 正确
};
funAdd12(1); // 正确// 函数重载
// 注意不能写const let定义,使用function定义
// 同样不能写箭头函数了
// 当你传入两种模式,代码层面做好判断即可;不同的参数返回不同的数据类型
function funAdd13 (x: number): number;
function funAdd13 (x: string): string;
function funAdd13 (x: number | string): number | string {// number => numberif(typeof x === 'number'){return x + 1;}// string => stringreturn x + '1';
};
funAdd13(1); // 2
funAdd13('hello'); // hello// 构造函数
// 函数默认是不能当成构造函数使用的
// const funAdd13_child = new funAdd13('hello'); // 报错// type 构造函数, new 关键字 开头
type FunAdd14_new = new (x: number) => object;type funAdd_type = {new (x: number): object;
}
// funAdd_type 只能和 Class 结合使用
class FunAdd14_class {constructor(public x: number) { this.x = x + 1;}
}
const funAdd14: funAdd_type = FunAdd14_class;
const funAdd14_child = new funAdd14(123); // 正确

4、对象类型

// 对象类型
// 字面量对象,注意可以使用, 或者;
// 属性个数固定,必须包含所有属性(有点类似于元组强制数量)
const objValue1: {name: string,age: number,sayHello: () => void; // 函数方式 1sayHello2(): void; // 函数方式 2count?: number // 可选属性
} = {name: 'vbj',age: 18,sayHello: () => {console.log(`hello ${this.name}`);}
};
console.log(`objValue1`, objValue1);
// 删除必选属性,不再被允许
// delete objValue1.name; // 错误
// 删除可选属性,可以被删除
delete objValue1.count; // 正确// type 定义对象类型
type ObjValue2 = {age: number[],name?: string,
}
// 获取某一个元素的类型;注意类型变量不是纯对象,不能使用 ObjValue2.name
type ObjValue2Name = ObjValue2['name']; // string// interface 定义对象类型
interface ObjValue3 {toString(): string;name: string;age?: number;
}
// 如果属性是构造函数自带的,可以省略(如 toString)
// 因为对象默认自带 toString 方法(Object.prototype.toString)
const objValue3: ObjValue3 = {name: 'vbj',age: 18,
};
// const objValue3Age = objValue3.age * 1; // 错误:不能使用 undefined 类型
if (objValue3.age) { // 正确; 可选值需要经过判断再使用;有点类似函数参数的可选const objValue3Age = objValue3.age * 1; // 正确
}// age1、age2这两个是不一样的
// 前面必须定义属性age1;age2可以有可以没有,只不过他们的值类型相似
type ObjValue4 = {age1: number | undefined,age2?: number,
}// readonly 关键字
type ObjValue5 = {readonly name: string,readonly age: number,readonly points: number[];readonly count: {count1: number,count2: number,}
}
const objValue4: ObjValue5 = {name: 'vbj',age: 18,points: [1, 2, 3],count: {count1: 100,count2: 200,}
};
// 浅层修改属性报错
// objValue4.name = 'hello'; // 错误// 深层属性修改; 正确
objValue4.points[0] = 100; // 正确
objValue4.count.count1 = 100; // 正确// 引用数据会突破readonly限制
// 内存数据优先于关键字
const objValue5 = {name: 'vbj',age: 18,points: [1, 2, 3],count: {count1: 100,count2: 200,}
}const objValue6:ObjValue5 = objValue5
objValue5.name = 'hello'; // 正确
console.log('objValue6', objValue6.name); // hello// 属性名索引(索引也具有类型)
// 注意索引类型只能写一个;比如 propName: string只能写一个type ObjValue7 = {[propName: number]: number,// [propName: string]: string, // 报错。索引代表的值类型冲突// string索引优先级更高,只要他的容错度高就可以[propName: string]: string | number,// [propName: string]: string | number | undefined,// 索引类型和普通类型,很容易冲突// name: boolean // 错误:[propName: string] 和 boolean 类型冲突
}// 解构赋值
// 注意单独的变量不能使用类型注解;只能集体使用;因为:号会被识别成变量别名
const { name: vbjName, age, points, count }: {name: string,age: number,
} = {name: 'vbj',age: 18,
}// 结构类型; 父类型,基础;子类型比父类性更加严格(包含父类型的属性)
const objPointA = {x: 1,y: 1
};const objPointB:{ x: number } = objPointA; // 正确for (const key in Object.keys(objPointB)) {// 报错;objPointB的值中可能出现除x以外的属性,默认为any// const item = objPointB[key];// 所以只能使用objPointB中确定的属性const item = objPointB.x;
}// 字面量和变量区别
function sayHelloObj({name: string}): void {}
const sayHelloObjParam = {name: 'vbj', age: 18};
sayHelloObj(sayHelloObjParam); // 正确;结构类型满足即可(参数可多不能少)
sayHelloObj({name: 123, age: 18}); // 错误:age类型不匹配; 字面量会匹配参数数量// 空对象
// 写空对象,会认为后续无法添加属性
const emptyObj: {} = {}; // 类型被锁定 const emptyObj: {}
// emptyObj.name = 'vbj'; // 报错const emptyObj2: Object = { name: 'vbj' };
emptyObj2.name = 'vbj'; // 报错// 初始化对象
// useState后的泛型区域内就是 countObject的类型;如果默认空对象,要给每个属性写可选类型
// const [countObject, setCountObject] = 
// useState<{ count?: number, age?: number }>({}); // 方式 1
// 或者给默认值
const defaultCountObject = { count: 0, age: 0 };
const [countObject, setCountObject] = 
useState<{ count: number, age: number }>(defaultCountObject);  // 方式 2
const countObjectValue = countObject?.count;
useEffect(() => {setCountObject({ count: 0, age: 18 }); // useState类型
}, []);

三、接口

// interface基础用法
interface Person {firstName?: string;lastName?: string; // 可选属性readonly age?: number; // 只读属性[key: string]: any; // 注意每一种key类型,只能有一种值类型[key: number]: string; // key number索引
}
const persons: Person = {firstName: 'John',lastName: 'Doe',age: 30,
};
// interface的数字索引可以定义数组
const personKeys: Person = ['firstName', 'lastName', 'age'];// interface的函数
interface Person2 {// interface 函数重载;注意只能写function,不能写箭头函数fun(name: string): string;// fun(name: number): number;fun1?: (age: number) => number;fun2?: { (name: string): void };
}
// 具体的重载,只能在具体函数体使用,interface重载只是定义
const person2: Person2 = {fun: function (name: string): string {return `hello ${name}`;},
};// 独立函数; (type可以更方便完成)
interface Person3 {(name: string, age: number): void;
}
const person3: Person3 = function (name: string, age: number): void {console.log(`hello ${name}, your age is ${age}`);
};
// 构造函数
interface Person4 {new (name: string, age: number): void;
}
class person4Class {name: any;age: any;constructor(name: any, age: any) {this.name = name;this.age = age;}
}
// 注意这里的Person4是接口,person4Class是类
const person4: Person4 = person4Class;// 继承
interface Animal {name: string;
}
interface AnimalColor {color: string;
}
// 当type是对象时,可以被继承
type AnimalType = {type: string;
};
// 继承Animal,AnimalColor; 注意属性不能重重复,否则报类型不兼容
interface Dog extends Animal, AnimalColor, AnimalType {bark(): void;// color: number; // 属性“color”的类型不兼容。
}
// 同名的interface会合并属性
// 当一个interface没有你想要的属性,又不想新增,可以直接合并
interface Dog {age: number; // 新增属性
}// type 和 interface 的区别
// 相同点
// 1. type都命名为对象的时候,基本一致
// 2. 可以定义属性类型// 不同点
// 1. interface 可以继承,type 不可以
// 2. interface 可以合并,type 不可以
// 3. interface 只能写对象,type 可以写任意类型(类型更灵活)
// 4. type 有联合类型、交叉类型,interface 没有
// 5. type 不能重复声明,interface 可以重复声明
// 6. interface 中使用 this 关键字,type 中不能使用// 个人总结
// 1. interface 用于组件参数列表,API接口参数定义,函数返回值,更多属于业务层面
// 2. type 用于复杂的类型定义,更多属于类型层面

四、泛型

// 泛型// 当参数和返回值有关系的时候,无法明显看出来关系// 即便是指定类型为一致,也只是表明他们类型恰好一致,而不是恒定一致性const getArrayFirst1 = (num: any[]): any => {return num[0];};// 写法 1 functionfunction getArrayFirst2<T>(num: T[]): T {return num[0];}// 写法 2 箭头函数// 注意 T后面有逗号const getArrayFirst3 = <T,>(num: T[]): T => {return num[0];};// 前面两种是根据值推到处类型,也可以主动设置类型// 写法 3 interfaceinterface GetArrayFirst4 {<T>(num: T[]): T;}const getArrayFirst5: GetArrayFirst4 = (num) => {return num[0];};// 泛型可以不写,默认根据实参推导getArrayFirst2([1, 2, "3"]); // <string | number>// 也可以指定类型;如果复杂的类型,尽可能主动传入泛型变量getArrayFirst2<string | number>([1, 2, "3"]);// interface + 泛型// interface 可以 动态设置类型interface GetArrayFirst6<T> {(num: T[]): T;}// 注意 interface有泛型时,必须使用,不能省略const getArrayFirst7: GetArrayFirst6<string | number> = (num) => {return num[0];};getArrayFirst7([1, 2, "3"]);// class + 泛型// 类也可以使用泛型class MyClassGetNum1<T> {// static num: T[] = []; // 报错;静态属性不能使用泛型;只能使用实例属性// constructor 相当于函数的参数入口constructor(public num: T[], ...args: any[]) {}getFirst(): T {return this.num[0];}}// T === string | number 默认根据实参推导const myClassNum1 = new MyClassGetNum1([1, 2, "3"]);// class 和构造函数的 关系// class 改造成 函数function MyClassGetNum1Func<U>(ClassCore: typeof MyClassGetNum1, num: U[], ...args: any[]): MyClassGetNum1<U> {return new ClassCore<U>(num, ...args);}// 注意 U 如果不传,会根据 存在的U推导;// 比如参数有U,传了参数但函数没有传U,会根据参数确定Uconst myClassNum2 = MyClassGetNum1Func(MyClassGetNum1, [1, 2, "3"]);console.log("myClassNum2", myClassNum2.getFirst());// type + 泛型type GetArrayFirst8<T> = (num: T[]) => T;const getArrayFirst9: GetArrayFirst8<string | number> = (num) => {return num[0];};getArrayFirst9([1, 2, "3"]);// 树形结构的 type type 可以使用自己type Tree<T> = {value: T;left?: Tree<T>;right?: Tree<T>;};const treeType: Tree<number> = {value: 1,left: {value: 2},right: {value: 9}};// 泛型默认值function getArrayFirst10<T = string>(num: T[]): T {return num[0];}// 函数没传泛型,根据参数推导,并且覆盖默认值getArrayFirst10([1, 2, "3"]);class MyClassGetNum2<T = string> {constructor(public num: T[]) {}// 可以设置在参数位置add(num: T): void {this.num.push(num);}}const myClassNum3 = new MyClassGetNum2([1, 2, "3"]);// 推导的泛型,会覆盖默认值// console.log("myClassNum3", myClassNum3.add(true)); // 报错// 数组泛型// Array 相当于一个 interfaceconst arrInterface1: Array<number> = [1, 2, 3];// 只读数组 ReadonlyArrayconst arrInterface2: ReadonlyArray<number> = [1, 2, 3];// arrInterface2.push(1); // 报错// arrInterface2 = []; // 报错// 泛型条件约束// 也就是说和默认类型不同,约束类型是不会被覆盖的,会和T一起构成联合类型// 简单说 A extends B 就是 A 必须是 B 的子类型;// A 范围小一些,B 范围大(条件宽松)// 注意 = 10 指的是T的默认值,不是stringfunction getArrayFirst11<T extends number | string = 10>(num: T[]): T {return num[0];}// 使用了 extends 约束,最好是主动传入泛型,而不是依赖默认推导getArrayFirst11<number | string>([1, 2, 3, 4, "5"]);// 1、泛型使用会增加复杂度,尽量不要滥用,超过 3 个重复的类型考虑使用泛型

五、enum

 // enum 枚举类型// 类似于js对象,编译后也是对象;enum这里的作用是提供 类型 + 枚举// 枚举值的特点是名称很重要(语义化),值可以变化程度大enum Color {// 枚举值可以不用从 0 开始,可以设置其他值Red,Yellow, // 默认自增 + 1Green = "Green",// 注意数字索引中断以后,不会默认自增,需要手动设置Blue = 0// obj = {//   name: "obj"// }}const color: Color = Color.Red;console.log("color", color);// 同名枚举值,会合并// 注意数字索引为0的位置,只有一个;其他的同名enum要手动设置enum Color {// Pink, // 0,但是报错,因为已经存在了Pink = "Pink"}// const enum// 编译后会直接替换成 值,不会生成对象; 提高了效率// 编译后// const color = 0;// 函数和 enum 类型// 当参数使用 enum,不能再传值,而是只能穿 enum 类型function getColor(color: Color): string {switch (color) {case Color.Red:return "红色";case Color.Yellow:return "黄色";default:return "未知";}}// console.log("getColor", getColor('Green')); // 报错,类型不匹配console.log("getColor", getColor(Color.Green)); // 正确// keyof 索引类型// 得到所有 key 的联合类型;typeof 是为了获取类型,keyof 获取 keytype Color_key = keyof typeof Color;// 获取了所有值 key 表示枚举的值type Color_value = { [key in Color]: any };// enum 反向映射// 枚举值可以反向映射到枚举名; 注意枚举值相同,反向映射得到最后一个// 注意使用[]反向映射也可以获取枚举值,获取枚举值尽量使用Color.Blue规范const color_reverse = Color[0]; // 0 映射到 Blue 而不是 Red// Color["123"] // 123 映射到 undefined// Color["Blue"] // Blue 枚举值 0// Color.Blue; // 0console.log("Color_key", color_reverse, );

六、断言

// 断言
type Person_As1 = {name: string;age: number;count: number;
}
const person_assert  = {name: 'vbj',
}
// 断言 即便不满足该类型,可以认为指定断言,这样可以绕过检查(可能导致异常)
const person_assert_type1: Person_As1 = person_assert as Person_As1;
// 当你定义数据初始化时,可能没有那么多数据,可以指定断言以后,逐步添加属性
person_assert_type1.age = 18;
console.log('person_assert_type1', person_assert_type1.count);// 使用断言的场景,很有可能你所使用的数据,是很模糊的
// 不确定有哪些属性,或者暂时没有; 这个时候很容易把父类性赋值给子类型
// 可以看到不满足条件也被定义了
const person_assert_type2: Person_As1 = {name: 'vbj',age: 18,count: 100,num: 100 
} as Person_As1// 断言条件
// 只要as右边是目标类型的子类型即可(子类型 = 父类性 + 额外属性)
// 比如 const value: T1 = valueDefault as T2;
// T2 必须是 T1 的子类型; 
// valueDefault是T2的子类型 或者 T2是valueDefault的子类型
const person_assert_type3: Person_As1 = {name: 'vbj',
} as { name: string, age: number, count: number, num: number }; // 正确// 最终把数字赋值给字符串
// 注意 any unknown 是所有类型的父类性
// const person_assert_type4: string = 100 as string; // 错误 as 两边的值类型不匹配
const person_assert_type4: string = 100 as unknown as string; // 正确 中转 unknown 类型// as const 关键字
// let const 关键词会导致变量的类型不一致(简单说const会让变量的类型固定)
// let string1: string
let string1 = 'JavaScript';
// const string2: "JavaScript"
const string2 = 'JavaScript';// let string3 = string1 as const; // 报错 as const 前面只能出现基本数据字面量,不能是变量
// let string3: "JavaScript"
let string3 = 'JavaScript' as const;// 对象字面量 + as const 关键字;
// 会导致对象属性变成只读readonly, 不能再添加属性; 
// 属性的值也被改成值类型,比如name类型不是string,而是'vbj'
const person_as_type5 = { name: 'vbj', } as const; // 正确,空对象类型
// person_as_type5.age = 1 // 错误,不能添加属性// 枚举值类型锁定
enum Person_enum1 {name,age = 'age',
}
let person_enum1 = Person_enum1.name;            // Person_enum1
let person_enum2 = Person_enum1.name as const;   // Person_enum1.name// 非空断言
function AsFun1(value: string | null): string {// 断言 value 非空,否则会报错; 这个例子中其实就是排除 null// 非空表示这里一定有值return value!.toUpperCase();
}// 断言函数(断言逻辑的复用)
// 这里断言只要是string类型,就抛出异常
// 注意 asserts value is string 只是语义化;具体逻辑需要自己设定
function isStringAs(value:unknown):asserts value is string {if (typeof value !== 'string')throw new Error('Not a string');
}
function AsFun2(value: string | number | null): string {isStringAs(value); // 调用断言函数// 如果断言函数使用得当,那么错误会出现在断言函数,不会在这里报错return value.toUpperCase();
}
AsFun2(null);

七、工具

1、模块

    // 模块// type 和 interface 区分// 类型定义文件:module_type.d.tsexport interface interfaceName {name: string;}export type typeName = {age: number;}export let num = 123;// 引入类型定义文件: const.ts// 方式 1; 单个确定为type类型import { type interfaceName, typeName } from './module_type';// 方式 2; 批量确定为type类型import type { interfaceName, typeName, num } from './module_type';const numCurrent = num; // 报错,num是类型,而不是值

2、namespace

    // namespace// 命名空间可以将类型定义文件拆分为多个文件,方便管理// 命名空间,可以导出和引入;// 如果未导出,外部无法访问;// 可以和函数重名,重名的时候,相当与给函数增加属性;function module_namespace1(){}namespace module_namespace1 {export interface interfaceName {name: string;}}// 同名的命名空间,会进行合并;// 注意,只会合并 export 的成员;namespace module_namespace1 {export let num = 123;let nullVar = null;}namespace module_namespace2 {import interfaceName = module_namespace1.interfaceName;import num = module_namespace1.num;// import nullVar = module_namespace1.nullVar; // 报错}

3、装饰器

    // 装饰器// 装饰器可以替换类中原有的方法、属性等function simpleDecorator() {console.log('hi');}function simpleDecoratorConstructor() {return function(target: any) {console.log('simpleDecoratorConstructor');}}@simpleDecorator// simpleDecorator 会附在A身上,当A加载就会调用 simpleDecorator// 注意有多个装饰器,靠近 A 的装饰器先触发class A {// 注意装饰器后的代码返回一个函数即可// simpleDecoratorConstructor 返回的函数会替换 getTarget 函数体@simpleDecoratorConstructor()getTarget(params: any) {console.log('A getTarget');}} // "hi"console.log('simpleDecorator', new A().getTarget(1));

4、declare

// declare 关键字// 当外部模块的变量没有类型,可以使用 declare 关键字声明变量类型// 不能赋值, 只能定义类型// declare let module_declare: string = 'hello'; // 报错declare let module_declare: string;module_declare = 'hello'; // 正确// declare module NAMEdeclare module 'antd' {export function message(content: string): void;}declare module '@ant-design/icons' {export function message(content: string): void;}// 强制模块export {};// 全局对象扩展// 注意,只能扩展属性,不能新增顶层对象declare global {interface String {toRaw(): string;}}String.prototype.toRaw = ():string => {return 'toRaw';};

5、运算符

    // 运算符type T5 = {name: string;age: number;};// 返回所有的属性名(可能找到原型链上)type T6 = keyof T5; // T6 是联合类型 "name" | "age"const t6: T6 = 'name'; // 正确,keyof T5 返回 T5 的属性名类型// 一般需要使用对象属性的时候使用,keyof 返回 属性名的联合类型const T7_Obj = {name: 'vbj',age: 18,};const T7_Key: string = 'name';function T7_Func(obj: T5, key: string) {return obj[key as keyof T5];}T7_Func(T7_Obj, T7_Key)// in 运算符 (类型中,而不是js的in运算符)type Type8 = {name: string;age: number;};// 类似于复制所有目标对象的属性到一个新对象中type Type9 = {[key in keyof Type8]: any;};// 方括号// 获取类型的属性值type Type10 = {name: string;age: number;[key:number]: boolean};// 因为是类型括号,所以括号中也可以穿入类型(类型括号不能变量值)// type Type = Type10['na' + 'me'] // 报错type Type10_number = Type10[number] // booleantype Type11 = Type10['name'] // string// 联合类型,也会被识别成联合类型type Type12 = Type10['name'|'age'] // string | number// extends 三元运算符// 条件判断,根据类型判断返回不同类型;公式:T extends U ? X : Y// T 是 U 的子类型,返回 X;否则,返回 Ytype Type13 = string extends string | number? string : number; // string// infer 关键字// infer 关键字可以帮助我们推导类型变量;这样可以得到一个主动推导的变量类型(element)type type14<Type> = Type extends Array<infer element> ? element : string;type type15 = type14<string[]>; // string// is 关键字// is 关键字可以判断一个变量是否是某个类型;相当于语义化,具体判断需要自行定义function isType10(a:string): a is string {console.log('isType10 Function');return typeof a ==='string';}if(isType10('isType10_result')){console.log('isType10_result');}// 类型中的字符串模板type Type16 = `hello ${string} world`; // "hello " + string + " world"// satisfies 关键字// 手动类型检测, 帮助你进行类型报错提示type Type17 = {name: string;age: number;};// 这里并不想指定类型,而使用默认推导;但是又希望推导的时候,能够进行属性校验// 主要是为了获取开发时的提示const Type17_Obj = {name: 'vbj',aeg: 18,count: 100,} satisfies Type17;const Type17_count = Type17_Obj.count;

6、映射类型

    // 映射类型// 映射类型可以帮助我们快速创建类型;// 语法:{ [K in keyof T]: X }// 其中,K 是 T 的属性名,X 是任意类型type Type18 = {name: string;readonly age: number;};// 注意前面的+、-、readonly,表示修改关键字,增加或去除只读性// +、-、?,表示增加或去除可选性type Type19 = {// count: number; // 如果映射,不能添加新属性// A as B 可以在之前的键名A基础上转换属性名B+readonly[P in keyof Type18 as `newkey ${P}`]+?: Type18[P];};

7、类型工具

    // 类型工具type Type20 = {name: string;age: number;}// 工具类型类似于语法糖// type Partial<T> = { [P in keyof T]?: T[P] | undefined; }type TypeTool1 = Partial<Type20>; // 所有属性可选type TypeTool2 = Required<Type20>; // 所有属性必填type TypeTool3 = Readonly<Type20>; // 所有属性只读type TypeTool4 = Pick<Type20, 'name' | 'age'>; // 选择性的属性type TypeTool5 = Omit<Type20, 'age'>; // 排除的属性 返回剩下的属性type TypeTool9 = Parameters<() => void>; // 参数类型 可以传入函数类型type TypeTool10 = ReturnType<() => string>; // 返回值类型 可以传入函数类型type TypeString1 = 'hello'type TypeString2 = Uppercase<TypeString1> // HELLO 字符串类类型大小写转换// 使用频率较高的类型工具// 快速创建未知数量属性的对象类型type Type21 = Record<string, any>; // 索引类型,可以指定索引类型

8、语法注释

    // 语法注释// @ts-nocheck 忽略检查const element = document.getElementById(123);// JSDoc 声明// JSDoc 注释可以帮助我们生成文档,同时也会帮助我们进行类型检查// 注意类型变量放在{}中/*** @param {string} name 这里的类型只是说明参数类型,不是实际类型; * @typedef {(number | string)} NumberLike 相当于创建type别名* @typed {NumberLike} 描述类型是什么,使用刚才定义的别名* @returns {void} 这里的类型只是说明返回值类型,不是实际类型;* @extends {HTMLElement} 继承自HTMLElement*/function NoteFun(name: number): string {console.log('Hello ' + name);return 'Hello';}

9、tsconfig.json

// tsconfig.json
//npm install -g typescript
// tsc --init 生成tsconfig.json文件
// 打包编译时会读取tsconfig.json配置
{"compilerOptions": {"outDir": "./dist", // 编译输出目录"allowJs": true, // 允许编译js文件"target": "es5", // 编译js的目标版本"jsx": "react", // 使用jsx, 规定输出的jsx文件名"lib": ["dom", "es2021"], // 编译时需要引入的内置的类型库"sourceMap": true, // 生成sourceMap文件"strict": true, // 开启严格模式"paths": {"@/*": ["src/*"] // 路径映射, 类似于webpack的resolve.alias}},"include": ["./src/**/*"] // 需要编译的文件列表
}

相关文章:

前端TS基础

文章目录 一、类型1、定义类型2、any、unknown、never3、基础类型4、联合类型5、交叉类型6、type、typeof7、作用域 二、数据结构1、数组2、元组3、函数类型4、对象类型 三、接口四、泛型五、enum六、断言七、工具1、模块2、namespace3、装饰器4、declare5、运算符6、映射类型7…...

前端面经每日一题day06

Cookie有什么字段 Name&#xff1a;cookie的唯一标识符 Value&#xff1a;与Name对应&#xff0c;存储Cookie的信息 Domain&#xff1a;可以访问cookie的域名 Path&#xff1a;可以访问cookie的路径 Expires/Max-Age&#xff1a;超时时间 Size&#xff1a;cookie大小 Ht…...

SOC,SOH含义区别及计算公式

SOC&#xff0c;SOH含义区别及计算公式 两者结合使用&#xff0c;有助于实现更精确的电池管理&#xff0c;延长电池的使用寿命&#xff0c;并确保电池的高效、安全运行。 1. SOC&#xff08;State of Charge&#xff0c;荷电状态&#xff09;2. SOH&#xff08;State of Health…...

阿里云轻量应用服务器开放端口,图文教程分享

阿里云轻量应用服务器如何开放端口&#xff1f;在轻量服务器管理控制台的防火墙中添加规则即可开通端口&#xff0c;开通80端口就填80&#xff0c;开通443就填443端口&#xff0c;开通3306端口就填3306。阿里云百科网aliyunbaike.com整理阿里云轻量应用服务器端口号开通图文教程…...

嵌入式里的“移植”概念

这里因为最近一年看到公司某项目很多代码上有直接硬件的操作&#xff0c;这里有感而发&#xff0c;介绍移植的概念。 一、硬件 先上一个图&#xff1a; 举个例子&#xff0c;大学里应该都买过开发板&#xff0c;例如st的&#xff0c;这里三个层次&#xff0c; 内核&#xff…...

深入探讨 AF_PACKET 套接字

AF_PACKET 套接字是一种用于直接访问网络接口(即网卡)的套接字类型&#xff0c;通常用于网络数据包捕获和分析。它允许应用程序直接与网络接口卡&#xff08;NIC&#xff09;交互&#xff0c;而不需要通过网络协议栈。从而可以发送和接收以太网帧。它提供了比普通TCP/UDP套接字…...

Redis的哨兵机制

目录 1. 文章前言2. 基本概念2.1 主从复制的问题2.2 人工恢复主节点故障2.3 哨兵机制自动恢复主节点故障 3. 安装部署哨兵&#xff08;基于docker&#xff09;3.1 安装docker3.2 编排redis主从节点3.3 编排redis-sentinel节点 4. 重新选举5. 选举原理6. 总结 1. 文章前言 &…...

CSS系列(1)-- 选择器体系详解

前端技术探索系列&#xff1a;CSS 选择器体系详解 &#x1f3af; 致读者&#xff1a;探索 CSS 选择器的奥秘 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 选择器体系&#xff0c;这是构建优雅样式表的基础。让我们一起学习如何精确地选中并控制网页中的…...

用Python开发打字速度测试小游戏

本文将带你一步步开发一个简单的打字速度测试小游戏,通过随机生成词组并计算用户输入速度,帮助提升打字技能。 一、功能描述 随机生成一段句子,用户需要尽快输入。计时功能,统计用户输入的总时长。对比正确率和速度,给出评分反馈。二、开发环境 语言:Python依赖库:pygam…...

基于gitlab API刷新MR的commit的指定status

场景介绍 自己部署的gitlab Jenkins,并已经设置好联动(如何设置可以在网上很容易搜到)每个MergeRequest都可以触发多个Jenkins pipeline&#xff0c;pipeline结束后会将状态更新到gitlab这个MR上希望可以跳过pipeline运行&#xff0c;直接将指定的MR的指定pipeline状态刷新为…...

服务器数据恢复—LINUX下各文件系统删除/格式化的数据恢复可行性分析

Linux操作系统是世界上流行的操作系统之一&#xff0c;被广泛用于服务器、个人电脑、移动设备和嵌入式系统。Linux系统下数据被误删除或者误格式化的问题非常普遍。下面北亚企安数据恢复工程师简单聊一下基于linux的文件系统&#xff08;EXT2/EXT3/EXT4/Reiserfs/Xfs&#xff0…...

Spark on Yarn安装配置,大数据技能竞赛(容器环境)

Spark on Yarn模式&#xff0c;即把Spark作为一个客户端&#xff0c;将作业提交给Yarn服务&#xff0c;由于在生产环境中&#xff0c;很多时候都要与Hadoop使用同一个集群&#xff0c;因此采用Yarn来管理资源调度&#xff0c;可以有效提高资源利用率。 环境说明&#xff1a; 服…...

遣其欲,而心自静 -- 33DAI

显然&#xff0c;死做枚举只能的50分。 错了4次总算对了。 大体思路&#xff1a; 因题目说只有两个因数&#xff0c;那么有两种情况&#xff1a; 1&#xff1a;两个质数相乘&#xff0c;如&#xff1a;3*515 5*745 等&#xff08;不包括5*525 或5*315 重复计算\ 因为3*5算了…...

No.25 笔记 | 信息收集与Google语法的实践应用

什么是信息收集&#xff1f; 信息收集&#xff08;Information Gathering&#xff09;是渗透测试的第一步&#xff0c;其目的是通过各种手段收集目标的漏洞和弱点&#xff0c;为后续的攻击策略提供依据。 正所谓“知己知彼&#xff0c;百战百胜”&#xff0c;信息收集的重要性…...

GitLab基础环境部署:Ubuntu 22.04.5系统在线安装GitLab 17.5.2实操手册

文章目录 GitLab基础环境部署&#xff1a;Ubuntu 22.04.5系统在线安装GitLab 17.5.2实操手册一、环境准备1.1 机器规划1.2 环境配置1.2.1 设置主机名1.2.2 停止和禁用防火墙1.2.3 更新系统 二、GitLab安装配置2.1 安装GitLab所需的依赖包2.2 添加GitLab存储库2.2.1 将GitLab存储…...

SpringBoot3配置文件

一、统一配置管理概述: SpringBoot工程下&#xff0c;进行统一的配置管理&#xff0c;你想设置的任何参数(端口号、项目根路径、数据库连接信息等等)都集中到一个固定位置和命名的配置文件(application.properties或application.yml)中 配置文件应该放置在Spring Boot工程的s…...

【机器学习】任务十二:循环神经网络

1.循环神经网络 1.1 什么是循环神经网络&#xff08;RNN&#xff09;&#xff1f; 循环神经网络&#xff08;Recurrent Neural Network, RNN&#xff09; 是一种用于处理序列数据的神经网络类型&#xff0c;它的主要特点是拥有循环连接&#xff0c;使得网络可以对序列中的每个…...

【返璞归真】-切比雪夫不等式(Chebyshev‘s Inequality)

切比雪夫不等式&#xff08;Chebyshev’s Inequality&#xff09; 切比雪夫不等式是概率论中的一个基本不等式&#xff0c;用于估计随机变量偏离其期望值一定范围的概率。它对于任何具有有限期望和有限方差的随机变量都成立。 公式表达 切比雪夫不等式的基本形式如下&#xf…...

【Django】在view中调用channel来主动进行websocket通信

前提&#xff1a;consumer中已经写好了建立连接的代码&#xff0c;并且能够成功把连接加入到通道层的组内 可以参考我的另一个博客&#xff1a; LuckySheet协同编辑后端示例(DjangoChannel,Websocket通信)_lucksheet 协同编辑-CSDN博客 我是懒得去折腾luckysheet的源码&…...

18.[极客大挑战 2019]BabySQL1

进入靶场 随便输输 再输输 可以判断是单引号闭合 再随便输输 查询字段数量 得&#xff0c;过滤了 关键字也过滤了 只能双写了 根据回显&#xff0c;这样可以&#xff0c;只是需要改改 1,2不行 1,2,3行 1,2,3,4不行 可以尝试得到库名&#xff0c;表名了 库名 database(…...

Python快速入门二:Python3 基础语法

一、编码 默认情况下&#xff0c;Python 3 源码文件以 UTF-8 编码&#xff0c;所有字符串都是 unicode 字符串。 当然你也可以为源码文件指定不同的编码&#xff1a; # -*- coding: cp-1252 -*-上述定义允许在源文件中使用 Windows-1252 字符集中的字符编码&#xff0c;对应适…...

1-1 C语言链表

目录 目录 1.0 定义 2.0 为什么使用链表 3.0 链表原理 4.0 创建链表节点 5.0 链表原理续 6.0 链表实现 6.0.1 创建节点 6.0.2 初始化链表 6.0.3 添加链表节点 6.0.4 循环遍历 6.0.5 插入节点 6.0.6 插入头结点main函数 7.0 完整代码 8.0 节点添加方案二 8.0.1 …...

[0629].第29节:配置中心业务规则与动态刷新

我的后端学习大纲 SpringCloud学习大纲 1、编码实现3377服务&#xff1a; 1.1.建module: 1.2.改pom: 1.3.写YML&#xff1a; 1.Nacos同Consul一样&#xff0c;在项目初始化时&#xff0c;要保证先从配置中心进行配置拉取&#xff0c;拉取配置之后&#xff0c;才能保证项目的正…...

mac: docker : Command not found解决

描述: 安装docker但是docker命令显示Command not found 分析: mac没有配置对应的环境变量 解决方案: 打开配置文件: vim ~/.zshrc写docker环境变量: export PATH"/Applications/Docker.app/Contents/Resources/bin:$PATH"保存退出: esc,输入wq,按enter 配置文…...

Django drf基于APIView 快速使用

1. 注册 # settings.pyINSTALLED_APPS [,rest_framework, ]2. 路由 from django.urls import pathurlpatterns [path(task/, views.TaskAPIView.as_view()) ]3. 视图 from rest_framework.views import APIView from rest_framework.response import Responseclass TaskAPIV…...

【MarsCode】每日一题数组 之 数字分组求偶数和

数字分组求偶数和 1.问题描述 问题描述 小M面对一组从 1 到 9 的数字&#xff0c;这些数字被分成多个小组&#xff0c;并从每个小组中选择一个数字组成一个新的数。目标是使得这个新数的各位数字之和为偶数。任务是计算出有多少种不同的分组和选择方法可以达到这一目标。 n…...

解决:error: subprocess-exited-with-error 的问题

系统和配置&#xff1a; ubuntu20.04 python3.10 torch2.5.1 pip install时报错如下 &#xff08;实际指令是&#xff1a;pip3 install -r drl_grasping/python_requirements.txt&#xff09; Collecting python-xlib>0.17 (from pynput1.7.6->-r drl_grasping/python_…...

使用腾讯混元(HunYuanVideo)视频模型FP8量化版本来生成绅士动画,模型体积30G,8G甜品卡可玩,2秒视频需要15分钟

腾讯混元(HunYuanVideo)视频模型发布以来&#xff0c;视频效果有口皆碑&#xff0c;但由于推理门槛比较高&#xff0c;消费级显卡用户望而却步&#xff0c;最近大神Kijai发布了FP8量化版本模型&#xff0c;使得甜品卡用户也有了一餐秀色的可能。 本次我们利用HunYuanVideo量化…...

使用Ancona安装node,安装vue

搜索Conda仓库中可用的Node.js版本 conda search nodejs 通过Conda安装Node.js conda install nodejs 检查已安装的Node.js版本 node -v 安装中国npm镜像&#xff08;cnpm&#xff09; conda install cnpm 使用cnpm全局安装Vue CLI cnpm install -g vue/cli...

如何“安装Android SDK“?

一、下载 https://android-sdk.en.softonic.com/ 二、解压&#xff08;不能有中文&#xff09; 三、配置环境变量 1、ANDROID_HOME&#xff1a;D:\android-sdk 2、在Path添加文件路径 四、验证 adb version...