Typecript学习笔记
1.interface 接口—implement实现
interface接口用来规定一组数据的数据类型和结构,相当于为代码提供一个标准或者一个契约,implements可以用来实现。
interface common (){ console.log('共同点') }
class a entends A implements common{ }
接口不只是规定类中的契约,也可以规定函数的参数结构、类型和返回值的类型。
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
let result = source.search(subString);
return result > -1;
}
接口中还可以规定可索引类型,索引值可以是数字也可以是字符串,可以像数组那样根据下标访问元素。可以给索引签名设置readonly,防止给索引赋值。
interface ReadonlyStringArray {
readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!
/ /接口也可以继承接口,
interface shape{size:number}
interface Square extends shape{colour:String}
let square = <Square>{ };
类静态部分和实例部分区别:constructor属于类的静态部分,当一个类实现一个接口只会检查实例部分.
interface ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick();
}
function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
return new ctor(hour, minute);
}
class DigitalClock implements ClockInterface {
constructor(h: number, m: number) { }
tick() {
console.log("beep beep");
}
}
class AnalogClock implements ClockInterface {
constructor(h: number, m: number) { }
tick() {
console.log("tick tock");
}
}
let digital = createClock(DigitalClock, 12, 17);
//function createClock函数中第一个参数要求符合ClockConstructor接口,
//ClockConstructor接口要求的是符合Clockinterface接口的实例
//而这个里面第一个参数是DigitalClock类,该类Clockinterface,所以是对的
let analog = createClock(AnalogClock, 7, 32);
//同上
2.class类和constructor构造函数
class和js中class的概念基本一致,constructor(){}是构造函数,用来规定变量和处理数据的一些逻辑,在用new关键字进行初始化的时候会默认执行一次构造函数。
extend可以实现继承,子类可以通过super来调用父类方法,在一个类中如果存在静态方法,可以直接调用,不需要实例化。
3.protected public 和private
private :仅仅能在定义他的这个类中进行在这个属性的访问和修改。在子类和类的实现的对象中都不能访问。在子类可以通过调用使用这个属性的方法来间接来使用这个属性。
protected:因为一个类可以化身为好多好多的对象。对于一些这些对象应该共有的一样的属性不应该让对象有访问和修改的权力。
对于protected声明的属性,可以在子类中访问和修改他。不能在实现对象中访问。
对于protectedshen声明的构造方法。则该方法只能在继承的子类中调用不能直接在创建对象的时候直接调用。即该类只能被继承却不能被实现。
4.any和void、never
any是任意类型都接受;
void是没有返回值,比如函数没有返回值时返回值类型就是void,类似空指针。
never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。
never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。 即使 any也不可以赋值给never。never一般是用来抛出错误的。
5.ts进阶知识点
交叉类型
理解成且,即多个interface接口约束
联合类型
理解成或,即满足一个interface接口约束即可
6.概念理解
- 泛型
泛型是 规定类型 复杂类型定义,用于提升复杂类型定义的灵活性,起参数化类型的作用,
let list: Array = [1, 2, 3]; - 元组tuple
允许一个已知数量和类型的数组,元素类型不必相同
/ / Declare a tuple type
let x: [string, number];
当额外补充其他元素时,会用联合类型代替,就是第三个及以后的元素是string或number - 数据结构type
数据结构赋值常用的业务场景,数据的赋值,函数的声明等
type C = { a: string, b?: number }
function f({ a, b }: C): void {
// …
} - 三个点代表展开操作符
…arr可以理解成arr里面的所有参数。
let first = [1, 2];
let second = [3, 4];
let bothPlus = [0, …first, …second, 5];
比如需要把字符串,布尔类型等数据全都放到数组里面,可以用泛型约束等方式解决。
范式 解决组件属性,通过泛型将props将数据返回组件。
7.额外的类型检查
加入一个接口全部是可选属性,然后传值并不包含结构所规定任何一个则会报错,
解决办法一是用断言;二是在接口额外添加的字符串签名索引,用于告诉ts会有其他的属性
interface SquareConfig {
color?: string;
width?: number;
}
//使用断言
let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);
//使用签名
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}
当自身明确知道某个变量类型,用断言绕开类型检查器来实现自己所需要的属性或方法。需要用断言 包含尖括号<>和as两种方式,react中只允许as形式的断言。
8.作用域
es6以前只有两种作用域,全局作用域(不加var)和函数作用域;
es6中引入了let const
var定义变量的弊端就是变量会提升,会先给变量一个undefined,在书写的地方在具体赋值,比如if里面的变量在外面也可以访问;
而且var可以多次声明同一个变量不会报错,比如两层for循环重复定义i;
for 循环嵌套setTimeout,引用的是一样的i变量,需要用立即执行函数捕获变量i(自执行函数或每次有一个独立的作用域)
let块级作用域和try catch类似,可以直观的理解为{ }才是可访问的范围;let可以存在作用域屏蔽,比如两个嵌套的for 循环,都用let定义i的话,内层的i可以屏蔽外层的i,就是可以不收外层循环的i的影响。
暂时性死区:let和const都是es6中的块级作用域,其实也会有变量提升,如果是var定义变量之前访问则是undefine,如果是let、const则会报错,因为形成了封闭作用域,是不可访问的,在赋值之前的这段时间称为暂时性死区。