TS基本的练习

发布时间 2023-03-28 11:36:09作者: 洛晨随风
//infer 推断一个变量的类型
type arr<T> = Array<T extends () => infer U ? U : string>;

//此时传入的类型T是number | string,不属于类型()=>infer U所以返回的是string
type menus = arr<number | string>;

//此时传入的类型T是函数返回boolean 属于类型()=>infer U所以返回的是函数类型,根据infer推断U的类型就是boolean
type menus1 = arr<() => boolean>;

type obj = {
    name: string;
    id: number;
};

// pick,就是从原始类型中截取部分类型做为新的类型使用
// 原始类型
interface TState {
    name: string;
    age: number;
    like: string[];
}
// 如果我只想要name和age怎么办,最粗暴的就是直接再定义一个(我之前就是这么搞得)
interface TSingleState {
    name: string;
    age: number;
}
// 这样的弊端是什么?就是在Tstate发生改变的时候,TSingleState并不会跟着一起改变
interface TSingleState extends Pick<TState, 'age' | 'like'> {}

// pick 第一个参数是要截取属性的目标,第二个参数是要截取的属性
type C = Pick<obj, 'id'>;

// 元组类型,元组类型的每个值类型和顺序都已经确定,添加的时候要按照定义的顺序添加
//as  const 会转化为readonly类型
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const;

let tom: [string, number];
tom = ['Tom', 25];
//后面再次添加数据的时候以[string, number]两个其中一个类型为参照,如果有其他类型就会报错
tom.push(1);
tom.push('male');
tom.push(1);

//实现一个Awaited方法,Promise的接口定义使用了PromiseLike
type Unwrap<T> = T extends PromiseLike<infer U> ? U : T;

// resolve类型实现是
// resolve<T>(value: T): Promise<Awaited<T>>;
// 所以传入的变量会做推断并且传回对应的类型
const resultPromise = Promise.resolve('sss');
type resultUnwrapType = Unwrap<typeof resultPromise>;

//Awaited接口,从promise中获取具体的返回类型
const a = Promise.resolve('123');

// reject的实现是
// reject<T = never>(reason?: any): Promise<T>;
// 所以reject不声明参数类型就会传回never类型
//const a =  Promise.reject('123');
type resultUnwrapType1 = Awaited<typeof a>;

//自定义一个if,可以不叫if,叫if1  if2....之类的也可以,这里主要是实现if的逻辑
type If<C extends boolean, T, F> = C extends true ? T : F;
type A = If<true, 'a', 'b'>; // expected to be 'a'
type B = If<false, 'a', 'b'>; // expected to be 'b'

// 自定义一个拼接属性
type Concat<T extends string[], U extends number[]> = [...T, ...U];
type Result = Concat<['1'], [2]>; // expected to be [1, 2]

type Fruits = 'apple' | 'banana' | 'peach' | 'orange';
type DislikeFruits = 'apple' | 'banana';

//交集,取DislikeFruits和Fruits都有的部分
type FloveFruits = Extract<Fruits, DislikeFruits>; // 等效于 type FloveFruits = "apple" | "banana"

//补集,取DislikeFruits没有的部分
type FloveFruits1 = Exclude<Fruits, DislikeFruits>; // 等效于 type FloveFruits1 = "peach" | "orange"

// 将元组转换一个value为true的对象
// 1.分解后类似于{
//    Kars: true;
//    Esidisi: true;
//  }['Kars']
//  相当于在数组取值能否取到
// 2.取到的话就是一个true值,如果是的话就返回true,数组没有的key肯定返回不是true,一般是any,这时候就用false代替,
// 利用这样的逻辑就实现了一个includes
type Includes<T extends any[], U> = {
    [K in T[number]]: true;
}[U] extends true
    ? true
    : false;

type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Santana', 1], 'Dio'>; // expected to be `false`

type IEqual<T, U> = (<X>() => X extends T ? 1 : 2) extends <X>() => X extends U ? 1 : 2
    ? true
    : false;

// type IEqual<T, U> = T extends U ? (U extends T ? 1 : 0) : 0;

type isPillarMen1 = IEqual<
    ['Kars', 'Esidisi', 'Wamuu', 'Santana', 1],
    ['Kars', 'Esidisi', 'Wamuu', 'Santana', 1]
>;

// type c = <T>() => T;
// const aaa: c = () => {
//  return null
// };
// aaa<number>();

type bbb = IEqual<1, true>;

function getUser(a: string[]) {
    return { name: 'xxx', age: 10 };
}
type GetUserType = typeof getUser;

// ReturnType,获取函数返回值的类型
type ReturnUserFunc = ReturnType<GetUserType>;
// Parameters,获取函数参数的类型
type ReturnUserParams = Parameters<GetUserType>;

// 链式调用,参考;https://ghaiklor.github.io/type-challenges-solutions/en/medium-chainable-options.html
type Chainable<P = {}> = {
    option<K extends string, T>(
        key: K extends keyof P ? never : K,
        value: T
    ): Chainable<P & { [key in K]: T }>;
    get(): P;
};

declare const config: Chainable;

const result = config
    .option('foo', 123)
    .option('name', 'type-challenges')
    .option('bar', { value: 'Hello World' })
    .get().name;
console.log();

type petsGroup = 'dog' | 'cat' | 'fish';
interface IPetInfo {
    name: string;
    age: number;
}

type IPets = Record<petsGroup, IPetInfo>;
const animalsInfo: IPets = {
    dog: {
        name: 'dogName',
        age: 2
    },
    cat: {
        name: 'catName',
        age: 3
    },
    fish: {
        name: 'fishName',
        age: 5
    }
};

interface PageInfo {
    title: string;
}

type Page = {
    home: string;
    about?: string;
    contact?: string;
};

const nav: Record<keyof Page, PageInfo> = {
    home: { title: 'a' },
    about: { title: 'b' },
    contact: { title: 'c' },
};



interface Foo {
    a: number
    b: number
}

type PartialFoo = Partial<Foo> // { a?: number, b?: number}
type PartialFoo1 =Pick<PartialFoo,'a'>

const ret:PartialFoo={
    a:1
}