1、 typescript
unde
2、基本类型
-
类型声明
-
类型声明是TS非常重要的一个特点。
-
通过类型声明可以指定TS中变量(参数、形参)的类型。
-
指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错。
-
简而言之,类型声明给变量设置了类型,使得变量只能存储某种类型的值。
-
语法:
-
let 变量:类型; let 变量:类型=值 function fn(参数:类型,参数:类型):类型{...}
-
-
-
自动类型判断
- TS拥有自动的类型判断机制。
- 当对变量的声明和赋值同时进行时,TS编译器会自动判断变量的类型。
- 所以如果你的变量的声明和赋值是同时进行的,可以省略掉类型声明。
类型 例子 描述 number 1、 -33、3.5 任意数字 string ‘hi'、hi 任意字符串 boolean true、false true或false 字面量 其本身 限制变量的值就是改字面量的值 * * 任意类型 unknown * 类型安全的any void 空值(undefined) 没有值(或undefined) nrver 没有值 不能是任何值 object {name:'张三'} 任意的JS对象 array [1,2,3] 任意JS数组 tuple [4,5] 元素,TS新增类型,固定长度数组 enum enum{A,B} 枚举,TS新增类型
-
number
-
字面量
-
let a:10; a=10; //a只能取10 //可以使用|来连接多个类型(联合类型) let b:'male'|'female'; b='male'; b='female'; let c:boolean | string; c=false; c='hello';
-
-
any——表示的是任意类型,一个变量设置类型为any后,相当于对该变量关闭了TS的类型检测(在TS中,不建议使用any类型)
-
//生命变量如果不指定类型,则TS解析器会自动判断变量的类型为any(隐式的any) let d; //显式的any let d:any; d=10; d='hello'; d=false;
-
-
unknown——表示未知类型的值
-
let e:unknown; e=10; e='hello'; e=true; let s:string; s=d; //d的类型是any,他可以赋值给任意变量 e='hello'; s=e; //错误 //unknown实际上就是一个类型安全的any //unknown类型的变量,不能直接赋值给其他变量。 if(typeof e==='string'){ s=e; } //类型断言,可以用来告诉解析器变量的实际类型。 s=e as string; s=<string>e;
-
-
void ——表示为空,以函数为例,就表示没有返回值
-
function fn():viod{ //没有返回值 }
-
-
never——表示永远不会返回结果。
-
function fn():never{ throw new Error('报错'); }
-
//如果变量的声明和赋值是同时进行时,TS可以自动对变量进行类型检测。
let a=false;
a=123; //错误 ,上面直接赋值false。默认给了类型
//JS中的函数是不考虑参数的类型和个数的
function sun(a,b){
return a+b;
}
eg
{
// 简单类型
let isDone: boolean = false;
let age: number = 123;
let str: string = '123';
let message: string = `hello ${str},age is ${age}`;
let u: undefined = undefined;
let n: null = null;
// undefined 和 null 是所有类型的子类型 (underfined类型赋值给number类型)
let num: number = undefined;
let str1: string = null;
//any类型
let notSure: any = 4;
notSure = '123123';
// 联合类型
let numberOrString: number | string = 123;
numberOrString = '123';
// numberOrString = false; //报错
// 数组(同种数据类型聚合在一起)
let arr: number[] = [1, 2, 3, 4]
let arr2: any[] = [1, 2, 3, 4, '5', { name: '123' }] //会丧失具体类型
// let arr1: number[] = [1, 2, 3, '4'] //报错,不能有字符串
arr.push(5);
// arr.push('5'); 报错 ,不能加字符串
// 类数组---
function test() {
console.log(arguments);
}
// 元组(来自函数式编程)
let user: [string, number] = ['csy', 20];
// user = ['csy', 2, false] //少一项和多一项都会报错
// 类 interface
interface Person {
name?: string, //加?表示可选属性,该属性可有可无
age: number, //
readonly id: number, //只读属性,表示只读
}
let csy: Person = { //对象里面缺少和多属性都报错
name: 'csy',
id: 123,
age: 20,
// gender:'male'
}
// csy.id = 1111; 报错,不能重新赋值
// 函数声明
function add(x: number, y: number = 10, z?: number): number { //可选参数放在最后面
if (typeof z === 'number') {
return x + y + z;
} else {
return x + y;
}
}
let result = add(3.5, 4, 6);
let result1 = add(3.5, 4);
// 函数表达式
let adds = (x: number, y: number, z?: number): number => {
return x + y + z;
}
const adds2: (x: number, y: number, z?: number) => number = adds
// 类class
class Animal {
public name: string; //公有
private name1: string; //私有。子类不允许访问
protected name2: string;//子类可以访问
readonly name3: string;//只读
static categoies: string[] = ['bird', 'asd']
static isAnimal(a: any): boolean {
return a instanceof Animal;
}
constructor(name: string) {
this.name = name
}
run() {
return `${this.name} is running`
}
}
const cat = new Animal('Tom');
console.log(cat.run());
class Dog extends Animal {
break() {
return `${this.name} is barking`
}
}
const dogs = new Dog('xixi');
console.log(dogs.break());
console.log(dogs.run());
class Cat extends Animal {
constructor(name) {
super(name)
console.log(this.name);
}
run() {
return 'nwe,' + super.run()
}
}
const mao = new Cat("asd");
console.log(mao.run())
// 修饰符public(公有)、 private(私有,只能在类中访问、在子类中都不能访问)|protected(子类可以访问)
//
// 类和接口
interface Radio {
switchRadio(): void;
}
interface Battery {
checkBattery(): void;
}
interface RadioWithBattery extends Radio {
checkBattery(): void
}
class RadioStatus implements Radio {
switchRadio() {
}
}
// class Cellphone implements Radio, Battery {
class Cellphone implements RadioWithBattery {
switchRadio(): void {
}
checkBattery(): void {
}
}
// enums 枚举 被赋值0,1,2,3,
// 加const变成常量枚举
const enum Direction {
Up,
Down,
Left,
Right = 'RIGHT'
}
console.log(Direction.Up); // 0
console.log(Direction[0]); // Up
// 泛型 generics0 T:占位符
function echo<T>(arg: T): T {
return arg;
}
const echoStr: string = '123';
const echoNum: number = 123;
const resultEcho = echo(echoStr);
const resultEcho1 = echo(echoNum);
const resultEcho2 = echo("qwe");
const resultEcho3 = echo(456);
console.log(resultEcho2)
function swap<T, U>(tuple: [T, U]): [U, T] { //元组
return [tuple[1], tuple[0]]
}
const resultSwap = swap(['string', 123]);
// resultSwap[1]. 能用到number的方法
// resultSwap[0]. 能用到string的方法
//约束泛型
function echoWithArr<T>(arg: T[]): T[] {
console.log(arg.length);
return arg;
}
const arrs = echoWithArr([1, 2, 3]);
interface IWithLeng {
length: number //
}
function echoWithLength<T extends IWithLeng>(arg: T): T {
console.log(arg.length);
return arg;
}
const EchoWithLengthStr = echoWithLength('str');
const echoWithLengthArr = echoWithLength([123, 1, 2, 3]);
const echoWithLengthObj = echoWithLength({ length: 123 }) //包含length属性,并且类型为number
//泛型-类
class Quene<T> { // 队列类
private data = [];
push(item: T) {
return this.data.push(item);
}
pop(): T {
return this.data.shift();
}
}
const quene = new Quene<number>();
quene.push(1);
console.log(quene.pop().toFixed());
const quene1 = new Quene<string>();
quene1.push('str');
console.log(quene1.pop().charAt);
const quene2 = new Quene<string | number>();
// quene2.push('123');
// console.log(quene2.pop().toLocaleString);
// quene2.push(123);
// console.log(quene2.pop());
interface KeyPair<T, U> {
key: T,
value: U
}
let kp1: KeyPair<number, string> = { key: 123, value: '123' }
let kp2: KeyPair<string, number> = { key: '123', value: 123 }
let keyarr: number[] = [1, 2, 3]
let keyarr2: Array<number> = [1, 2, 3]
interface Ipus<T> {
(a: T, b: T): T
}
function plus(a: number, b: number): number {
return a + b;
}
function connect(a: string, b: string) {
return a + b
}
const plusres: Ipus<number> = plus;
const connectres: Ipus<string> = connect
// type alises 类型别名
type PlusType = (x: number, y: number) => number
function su(x: number, y: number): number {
return x + y;
}
const su1: PlusType = su
type NameResolver = () => string;
type NameOrResolver = string | NameResolver
function getName(n: NameOrResolver): string {
if (typeof n === 'string') {
return n
} else {
return n();
}
}
// type assertion 类型断言
function getLength(value: string | number): number {
// const = value as String;
// if (str.length) {
// return str.length
// } else {
// const number = value as Number;
// return number.toString().length
// }
if ((<string>value).length) {
return (<string>value).length
} else {
return value.toString.length
}
}
// 第三方库引用
// jQuery("#qaa").innerHeight
}
useEffect
理解
用于处理组件中的副作用,用来取代生命周期函数。
useEffect(()=>{
//代码
return ()=>{} //返回函数
},[参数])
场景
依赖参数不同时有不同的效果:
为空: 组件的任何更新,该 useEffect 对应的返回函数和函数都执行
为空数组: 不监听组件的更新
数组中有具体依赖:对应的依赖数据,有变化的时候,才会执行
- 组件挂载完之后做某事
useEffect(()=>{
console.log("组件挂载完之后执行");
return ()=>{
}
},[]);
- 组件挂载完成及更新完成做某事
useEffect(()=>{
console.log("组件挂载完成之后及更新完成之后执行");
})
- 组件更新完做某事
const isMounted = useRef(false);
useEffect(()=>{
if(isMounted.current){
console.log("组件更新完成")
} else {
isMounted.current = true;
}
})
- 组件即将卸载做某事
useEffect(()=>{
return ()=>{
console.log("组件即将卸载时执行");
}
},[]);