TS基本的练习
//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
}
积累小的知识,才能成就大的智慧,希望网上少一些复制多一些原创有用的答案