ts:类型操作关键词

发布于:2024-05-20 ⋅ 阅读:(47) ⋅ 点赞:(0)

1. keyof

用于获取对象所有键的类型组成的联合类型。
keyof T 在 TypeScript 中得到的是一个字符串字面量联合类型

1) 基本用法
interface Person {
    name: string;
    age: number;
}
let person: Person = {
    name: 'Jarid',
    age: 35
};
let personProps: keyof Person; // 'name' | 'age'
2) 映射类型
interface Person {  
    name: string;  
    age: number;  
    address?: string; // 可选属性  
} 

type Partial2<T> = {  
    [P in keyof T]?: T[P];  
};  
  
type PersonPartial = Partial2<Person>; // 等价于 { name?: string; age?: number; address?: string; }
3) 结合使用keyof和typeof来从对象实例中获取键的联合类型。
const myObject = {  
    a: 1,  
    b: 2,  
    c: 3,  
};  
  
type MyObjectKeys = keyof typeof myObject; // 等价于 "a" | "b" | "c"

2. extends

extends 关键字有两个主要用途:一是用于定义类(class)的继承,二是用于接口(interface)的扩展。

1. 类(Class)的继承
class Animal {  
    name: string;  
  
    constructor(name: string) {  
        this.name = name;  
    }  
  
    speak() {  
        console.log(`The animal speaks.`);  
    }  
}  
  
class Dog extends Animal {  
    bark() {  
        console.log('The dog barks.');  
    }  
  
    // 重写父类的 speak 方法  
    speak() {  
        super.speak(); // 调用父类的 speak 方法  
        console.log('The dog says woof woof.');  
    }  
}  
  
const dog = new Dog('Buddy');  
dog.speak(); // 输出: The animal speaks. The dog says woof woof.  
dog.bark(); // 输出: The dog barks.

2) 接口(Interface)的扩展
interface Shape {  
    color: string;  
    area(): number;  
}  
  
interface Rectangle extends Shape {  
    width: number;  
    height: number;  
    area(): number; // 这里可以重写父接口的方法,但通常不需要(除非有不同的实现)  
}  
  
// Rectangle 接口的具体实现  
class RectangleImpl implements Rectangle {  
    color: string;  
    width: number;  
    height: number;  
  
    constructor(color: string, width: number, height: number) {  
        this.color = color;  
        this.width = width;  
        this.height = height;  
    }  
  
    area(): number {  
        return this.width * this.height;  
    }  
}  
  
const rect = new RectangleImpl('blue', 10, 5);  
console.log(rect.area()); // 输出: 50

3. in

用于检查对象(包括对象字面量、类实例、接口实现等)是否包含某个特定的属性或索引

1) 检查索引
const array: number[] = [1, 2, 3];  
if (0 in array) {  
    console.log('Index 0 exists in the array');  
}

2) 检查属性

interface Person {  
    name: string;  
    age: number;  
    // 可能还有其他属性...  
}  
  
const person: Person = {  
    name: 'John Doe',  
    age: 30  
};  
  
// 使用 in 关键字检查 person 对象是否包含某个属性  
if ('name' in person) {  
    console.log(`person has a name: ${person.name}`);  
}  
  
if ('occupation' in person) {  
    // 这行代码不会执行,因为 person 对象中没有 occupation 属性  
    console.log(`person has an occupation: ${person.occupation}`);  
} else {  
    console.log('person does not have an occupation');  
}  
  
// 也可以用于数组索引检查  
const numbers: number[] = [1, 2, 3, 4, 5];  
if (1 in numbers) {  
    console.log('Index 1 exists in the array');  
}  
  
// 注意:'length' 也是一个属性,所以 'length' in numbers 也会返回 true  
if ('length' in numbers) {  
    console.log('Array has a length property');  
}

4. typeof

用于获取一个变量或属性的类型,但是在ts中获取如对象的类型不是像js中返回’object’而是对象的类型字面量

const myObject = {
    a: 1,  
    b: 2,  
    c: 3,  
};  
  
type MyObjectKeys =  typeof myObject; 
// MyObjectKeys 为 type MyObjectKeys = {
//     a: number;
//     b: number;
//     c: number;
// }

5.Pick

从一个对象类型中选择一部分属性来创建新类型的

interface Person {  
    name: string;  
    age: number;  
    location: string;  
    hobbies: string[];  
}  
  
// 使用 Pick 挑选 name 和 age 属性  
type PersonNameAge = Pick<Person, 'name' | 'age'>;  
  
// 现在 PersonNameAge 是一个新类型,它只包含 name 和 age 属性  
const person: PersonNameAge = {  
    name: "Alice",  
    age: 30  
    // location 和 hobbies 属性在这里是不允许的,因为它们没有被 Pick 出来  
};  
  
// 如果尝试添加其他属性,TypeScript 会报错  
// const wrongPerson: PersonNameAge = {  
//     name: "Bob",  
//     age: 25,  
//     location: "Home" // 错误:类型“{ name: string; age: number; location: string; }”的属性“location”在类型“PersonNameAge”中不存在。  
// };