Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「重学TS 2.0 」TS 练习题第三十六题 #55

Open
semlinker opened this issue Sep 22, 2021 · 13 comments
Open

「重学TS 2.0 」TS 练习题第三十六题 #55

semlinker opened this issue Sep 22, 2021 · 13 comments

Comments

@semlinker
Copy link
Owner

实现一个 Filter 工具类型,用于根据类型变量 F 的值进行类型过滤。具体的使用示例如下所示:

type Filter<T extends any[], F> = // 你的实现代码

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

请在下面评论你的答案

@zhaoxiongfei
Copy link

type Filter<T extends any[], F, A extends any[] = []> = T extends [infer Head, ...infer Tail]
  ? Head extends F
    ? Filter<Tail, F, [...A, Head]>
    : Filter<Tail, F, A>
  : A;

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

@xiaoYuanDun
Copy link

这题容易遗漏的地方是,需要判断当前类型是否为 any,其他没什么难度

// 判断当前类型是否为 any
type IsAny<T> = 0 extends (1 & T) ? true : false 

// 实现一个 Filter 工具类型,用于根据类型变量 F 的值进行类型过滤。具体的使用示例如下所示:
type Filter<T extends any[], F> = T extends [infer R1, ...infer R2] 
  ? IsAny<R1> extends true
    ? [R1, ...Filter<R2, F>]
    : [...R1 extends F ? [R1] : [], ...Filter<R2, F>]
  : []

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

@semlinker
Copy link
Owner Author

any 类型是个 ”黑洞“ 会吞噬除了 never 类型之外的大多数类型。本道题的关键点就是对 any 类型的处理。

type A0 = any & 1 // any
type A1 = any & boolean // any
type A2 = any & never // never

@sunboyZgz
Copy link

type Filter<T extends any[], F, Result extends any[] = []> = T extends [
  infer H,
  ...infer R
]
  ? [H] extends [F]
    ? Filter<R, F, [...Result, H]>
    : Filter<R, F, [...Result]>
  : Result;

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]
const test2: F2 = [1, "abao"];

@ln0y
Copy link

ln0y commented Sep 28, 2021

  type Filter<T extends any[], F> =
    T extends [infer A, ...infer B] ? [A] extends [F] ? [A, ...Filter<B, F>] : Filter<B, F> : []

@zhaoxiongfei
Copy link

type Filter<T extends any[], F, R extends any[] = []> = T extends [infer A, ...infer B]
  ? [A] extends [F]
    ? Filter<B, F, [...R, A]>
    : Filter<B, F, R>
  : R;

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]
type F3 = Filter<[never, number | string, any, "abao"], string>; // [never, any, "abao"]

思路: 利用 extends [infer A, ...infer B] 来提取数组内的第一项,递归这样就能提取到全部的,之后判断的类型的时候转换成元组类型[A] extends [F] 这样能避免出现的联合类型分发执行的问题。
never能匹配到任何类型上,这个题目没有说明,如果有说明的话,要特殊处理

@mingzhans
Copy link

mingzhans commented Oct 7, 2021

type Filter<T extends any[], F, R extends any[] = []> = T extends [infer A, ...infer B] ?  ([A] extends [F] ? Filter<B, F, [...R, A]> : Filter<B, F, R>) : R// 你的实现代码

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

any extends others 会走true分支,也会走false分支

@Cxdhz
Copy link

Cxdhz commented Nov 22, 2021

// 可以把判断逻辑写在值里,能减少一次三元运算符的使用
type Filter<T extends any[], F, R extends F[] = []> = 
  T extends [infer A, ...infer B] 
  ? Filter<B, F, [A] extends [F] ? [...R, A] : R>
  : R

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

@jackwangwj
Copy link

type Filter<T extends any[], F, U extends F[] = []> = T extends [infer A, ...infer Rest]
? [A] extends [F]
? Filter<Rest, F, [...U, A]>
: Filter<Rest, F, U>
: U
// 你的实现代码

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

@zjxxxxxxxxx
Copy link

type Filter<T extends any[], V> = T extends [infer F, ...infer R]
  ? [F] extends [V]
    ? [F, ...Filter<R, V>]
    : Filter<R, V>
  : [];

@ChuTingzj
Copy link

// 实现一个 Filter 工具类型,用于根据类型变量 F 的值进行类型过滤。具体的使用示例如下所示:
// type Filter<T extends any[], F> = // 你的实现代码
// type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
// type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
// type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

//answer  🔔any、never为联合类型,使用[]包装阻止类型分发
type Filter<T extends any[], F, Result extends any[] = []> = T extends [infer N, ...infer L] ? (N[] extends F[] ? Filter<L, F, [...Result, N]> : Filter<L, F, Result>) : Result
type F0 = Filter<[6, 'lolo', 7, 'semlinker', false], number> // [6, 7]
type F1 = Filter<['kakuqo', 2, ['ts'], 'lolo'], string> // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, 'abao'], string> // [any, "abao"]

@liziqiang
Copy link

type Filter<T extends any[], F, R extends any[] = []> = T extends [infer Head, ...infer Rest] ? Head extends F ? Filter<Rest, F, [...R, Head]> : Filter<Rest, F, R> : R;// 你的实现代码

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

@dolphin0618
Copy link

dolphin0618 commented Jul 23, 2022

type Filter<T extends any[], F, R extends F[] = []> = T extends [infer A, ...infer B] ?
  Filter<B, F, [A] extends [F] ? [...R, A] : R>
  : R

type F0 = Filter<[6, "lolo", 7, "semlinker", false], number>; // [6, 7]
type F1 = Filter<["kakuqo", 2, ["ts"], "lolo"], string>; // ["kakuqo", "lolo"]
type F2 = Filter<[0, true, any, "abao"], string>; // [any, "abao"]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests