工作笔记_ts

// 构造类型 T ,并将它所有的属性设置为可选的。  
// 返回值表示输入类型的所有子类型。

// Partial<T>

// interface Todo {
//     title: string;
//     description: string;
// }

// function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
//     return { ...todo, ...fieldsToUpdate };
// }

// const todo1 = {
//     title: 'hahhah',
//     description: 'hahhahahahhahahah'
// }

// const todo2 = updateTodo(todo1, { description: '啊啊啊啊啊啊啊' });


// Readonly<T> 

// 构造类型 T ,并将它所有的属性设置为 readonly,也就是说构造出来的类型的属性不能再次被赋值。

// interface Todo {
//     title: string;
// }

// const todo: Readonly<Todo> = {
//     title: 'Delete inactive users',
// };

// todo.title = 'Hello'; // Error: cannot reassign a readonly property

// 这个工具可用来表示在运行时会失败的赋值表达式(比如:当尝试给冻结对象的属性再次赋值时)

// Object.freeze

// function freeze<T>(obj: T): Readonly<T>;


// Record<K,T>
// 构造一个类型,其属性值的类型为 T 。这个工具可用来将某个类型的属性映射到另一个类型上。

// interface PageInfo {
//     title: string;
// }

// type Page = 'home' | 'about' | 'cantact';

// const x: Record<Page, PageInfo> = {
//     about: { title: 'about' },
//     cantact: { title: "cantact" },
//     home: { title: 'home' }
// }


// Pick<T,K>

// 从类型 T 中挑选部分属性 K 来构造类型

// interface Todo {
//     title: string;
//     description: string;
//     completed: boolean;
// }

// type TodoPreview = Pick<Todo, 'title' | 'completed'>;

// const todo: TodoPreview = {
//     title: 'hahhahahhaha',
//     completed: false
// }

// Omit<T,K>
// 从类型 T 中获取所有属性,然后从中剔除 K 属性后构造一个类型。

// interface Todo {
//     title: string;
//     description: string;
//     completed: boolean;
// }

// type TodoPreview = Omit<Todo, 'description'>;

// const todo: TodoPreview = {
//     title: 'Clean room',
//     completed: false,
// };


// Exclude<T,U>

// 从类型 T 中剔除所有可以赋值给 U 的属性,然后构造一个类型。

// type T0 = Exclude<'a' | 'b' | 'c', 'a'>;

// type T1 = Exclude<'a' | 'b' | 'c', 'a' | 'b'>;

// type T2 = Exclude<string | number | (() => void), Function>;

// Extract<T,U>

// 从类型 T 中提取所有可以赋值给 u 的类型,然后构造一个类型。
// type T0 = Extract<'a' | 'b' | 'c', 'a' | 'f'>;

// type T1 = Extract<string | number | (() => void), Function>;


// NonNullabel<T>

// 从类型 T 中剔除 null 和 undefined ,然后构造一个类型。


// type T0 = NonNullable<string | number | undefined>;
// type T1 = NonNullable<string[] | null | undefined>;

// ReturnType<T>
// 由函数类型 T 的返回值类型构造出一个类型

// type T0 = ReturnType<() => string>;
// type T1 = ReturnType<(s: string) => void>;
// type T2 = ReturnType<(<T>() => T)>;

// type T3 = ReturnType<(<T extends U, U extends number[]> () => T)>;
// type T4 = ReturnType<typeof f1>;  // { a: number, b: string }
// type T5 = ReturnType<any>;
// type T6 = ReturnType<never>;
// type T7 = ReturnType<string>;
// type T8 = ReturnType<Function>;


// InstanceType<T>

// 由构造函数类型 T 的实例类型构造一个类型。

// class C {
//     x = 0;
//     y = 1;
// }

// type T0 = InstanceType<typeof C>;
// type T1 = InstanceType<any>;
// type T2 = InstanceType<never>;
// type T3 = InstanceType<string>;
// type T4 = InstanceType<Function>;

// Required<T>

// 构造一个类型,使类型 T 的所有属性为 required

// interface Props {
//     a?: number;
//     b?: string;
// }
// const obj: Props = { a: 5 };
// const obj2: Required<Props> = { a: 5 };

// ThisType<T>

// 这个工具不会返回一个转换后的类型。它做为上下文的 this 类型的一个标记。注意,若想使用此类型
// ,必须启用 --noImplicitThis


type ObjectDescriptor<D, M> = {
    data?: D;
    methods?: M & ThisType<D & M>;
}


function makeObject<D, M>(desc: ObjectDescriptor<D, M>): D & M {
    let data: object = desc.data || {};
    let methods: object = desc.methods || {};
    return { ...data, ...methods } as D & M;
}

let obj = makeObject({
    data: { x: 0, y: 0 },
    methods: {
        moveBy(dy: number, dy: number) {
            this.x += dx;
            this.y += dy;
        }
    }
})

obj.x = 10;
obj.y = 20;
obj.moveBy(5, 5);
// interface Person {
//     firstName: string;
//     lastName: string;
// }

// function greeter(person: Person) {
//     return "Hello, " + person.firstName + " " + person.lastName;
// }

// let user = { firstName: "Jane", lastName: "User" };

// document.body.textContent = greeter(user);




// function aa(obj: { label: string }) {
//     console.log(obj.label)
// }

// let myobj = { size: "10", label: '少时诵诗书' };

// aa(myobj);





// interface Point {
//     readonly x: number;
//     readonly y: number;
// }
// let p1: Point = { x: 10, y: 20 };
// // p1.x = 5;




// TypeScript具有 ReadonlyArray<T> 类型,它与 Array<T> 相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改:

// let a: number[] = [1, 2, 3, 4, 5];
// let ro: ReadonlyArray<number> = a;
// // ro[0] = 12;
// // ro.push(5);
// // ro.length = 100;
// // a = ro;

// 可以看到,就算把整个 ReadonlyArray 赋值到一个普通数组也是不可以的。但是你可以用类型断言重写:

// a = ro as number[];



// readonly vs const 
// 做为变量使用用 const ,若作为属性使用 readonly




// function identity(arg: number): number {
//     return arg;
// }

// function identity(arg: any): any {
//     return arg;
// }


function identity<T>(arg: T): T {
    return arg;
}

let output = identity<string>('myString');
let output_ = identity('myString');


// 我们给 identity 添加了类型变量 T, T 帮助我们捕获用户传入的类型(比如:number),之后我们就可以使用这个类型。之后我们再次使用了 T 当作返回值类型。现在可以知道参数类型与返回值类型是相同的了。这允许我们跟踪函数里使用的类型的信息。

// 我们把这个版本的 identity 函数叫做泛型,因为它适用于多个类型。不同于使用 any ,它不会丢失信息,保持准确性,

// 定义了泛型函数后,可以用两种方法使用,第一种是,传入所有的参数,包含类型参数:

// 第二种方法更普遍,利用了类型推论---即编译器会根据传入的参数自动的帮我们确定T的类型。


function ssssss<T>(arg: T[]): T[] {
    console.log(arg.length);
    return arg;
}

function bbbbb<T>(arg: Array<T>): Array<T> {
    console.log(arg.length);
    return arg;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值