TS学习笔记(接口)

https://ts.xcatliu.com/basics/type-of-array

 

一个函数需要的参数是一个固定的结构

接口可以帮我们定义这种类型

接口规定数据类型的 可以是对象类型(参数类型) 也可以是类的类型  函数的类型 总之是用来定义类型的

interface b

简单理解 需要a:b (需要的参数a 是接口b这种类型的)

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);


//需要注意的是  类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。
//换句话说  传入的参数 只要包含接口定义的属性并且类型正确就可以了  不用管他在哪 以及多属性的前后顺序 

有些时候我们不是一定要某些参数 而是在一定条件下要一些参数

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});


//加一个? 即可 成为可选属性

只读属性

interface Point {
    readonly x: number;
    readonly y: number;
}
//用 readonly  来定义 只读属性
//定义后
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!



//数组只读 不可修改
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a; //ro是一个只读数组  他的值是数组a
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!

readonly vs const

最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用const,若做为属性则使用readonly

额外的属性检查

如果一个对象字面量存在任何“目标类型”不包含的属性时,你会得到一个错误。

interface SquareConfig {
    color?: string;
    width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
    // ...
}

let mySquare = createSquare({ colour: "red", width: 100 });


// error: 'colour' not expected in type 'SquareConfig'
let mySquare = createSquare({ colour: "red", width: 100 });

//绕过ts的额外属性检查 最简单的方法 就是使用类型断言 可看官网文档
//最好的方法 添加一个字符串索引签名  不明白什么意思 没关系 直接看例子就能懂了


interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
}
//在这我们要表示的是SquareConfig可以有任意数量的属性,并且只要它们不是color和width,那么就无所谓它们的类型是什么(类型 any)。


函数类型的接口

即定义一个函数的类型 

interface SearchFunc {
  (source: string, subString: string): boolean;
}

//()参数列表  (): 返回值类型

函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配。 但是对应位置的参数类型一定要匹配

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
  let result = src.search(sub);
  return result > -1;
}
//完全没问题

//但是如果 return 一个数字或者字符串 编译ts 就会报错 警告我们函数的返回值类型与 SearchFunc接口中的定义不匹配。

可索引的类型接口

//可索引类型具有一个 索引签名,它描述了对象索引的类型,还有相应的索引返回值类型。

 interface StringArray {
  [index: number]: string;
}

//[]定义索引类型 : 返回值

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];

TypeScript支持两种索引签名:字符串和数字。 可以同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值类型子类型

class Animal {
    name: string;
}
class Dog extends Animal {
    breed: string;
}

// 错误:使用数值型的字符串索引,有时会得到完全不同的Animal!
interface NotOkay {
    [x: number]: Animal;
    [x: string]: Dog;
}

字符串索引签名  会确保所有属性其返回值类型相匹配。

interface NumberDictionary {
  [index: string]: number;
  length: number;    // 可以,length是number类型
  name: string       // 错误,`name`的类型与索引类型返回值的类型不匹配
}

可以将索引签名设置为只读,这样就防止了给索引赋值:

interface ReadonlyStringArray {
    readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // error!

类类型的接口

类使用接口的关键字implements

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

//类静态部分与实例部分的区别

interface ClockConstructor {
    new (hour: number, minute: number);
}

class Clock implements ClockConstructor {
    currentTime: Date;
    constructor(h: number, m: number) { }
}

//会报错 这是因为只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。 所以实力部分并没有定义new(..)

如何设置类的静态解构:

interface claaA {
    new(name: string, age: number);
}
interface classB {
    con()
}
function creat(c: claaA, name: string, age: number): classB {
    return new c(name, age);
}
class A implements classB {
    constructor(name: string, age: number) { }
    con() { console.log("123") }
}
let a = creat(A, "张三", 12)

//个人理解 类A 是参数c要符合claaA的类型 则有一个new() 构造函数 即有了constructor并且传入的值要一致

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值