awesome-typescript icon indicating copy to clipboard operation
awesome-typescript copied to clipboard

「重学TS 2.0 」TS 练习题第二十三题

Open semlinker opened this issue 4 years ago • 14 comments

实现一个 RemoveIndexSignature 工具类型,用于移除已有类型中的索引签名。具体的使用示例如下所示:

interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type RemoveIndexSignature<T> = // 你的实现代码

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

请在下面评论你的答案。

semlinker avatar Sep 20 '21 12:09 semlinker

interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type RemoveIndexSignature<T> = {
  [key in keyof T as string extends key ? never : number extends key ? never: key]: T[key] 
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

zerolee1231 avatar Sep 20 '21 16:09 zerolee1231

interface Foo {
  [key: string]: any
  [key: number]: any
  bar(): void
}

type GetKey<V1, V2> = V1 extends V2 ? never : V2

type RemoveIndexSignature<T> = {
  // GetKey 中只要有一个是 never,那么交叉类型就是 never
  [K in keyof T as GetKey<string, K> & GetKey<number, K>]: T[K]
}

type FooWithOnlyBar = RemoveIndexSignature<Foo> //{ bar: () => void; }

Col0ring avatar Sep 20 '21 20:09 Col0ring

type RemoveIndexSignature<T> = {
  [key in keyof T as symbol extends key? never
    : `${any}` extends key? never
    : number extends key? never
    : key]: T[key];
};

ppbl avatar Sep 20 '21 20:09 ppbl

// 实现一个 RemoveIndexSignature 工具类型,用于移除已有类型中的索引签名。具体的使用示例如下所示:

interface Foo {
  [key: string]: any;
  [key: number]: any;
  [key: symbol]: any;
  bar(): void;
}

type RemoveIndexSignature<T> = {
  [k in keyof T as string extends k ? never : number extends k ? never : symbol extends k ? never : k]: T[k];
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

思路:这里利用的是 [k in as ]的用法。as过的语法可以直接实现对k的判断过滤

zhaoxiongfei avatar Oct 02 '21 09:10 zhaoxiongfei

interface Foo {
    [key: string]: any;
    [key: number]: any;
    bar(): void;
}

type RemoveIndexSignature<T> = {
    [K in keyof T as  string extends K ? never : number extends K ? never : K]: T[K]
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

Mrlgm avatar Oct 08 '21 08:10 Mrlgm

export default {}

// 实现一个 RemoveIndexSignature 工具类型,用于移除已有类型中的索引签名。具体的使用示例如下所示: interface Foo { [key: string]: any; [key: number]: any; bar(): void; }

type RemoveIndexSignature<T> = { [P in keyof T as P extends ${infer L}${infer R} ? P : never]: T[P] }

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

a572251465 avatar Dec 03 '21 04:12 a572251465

interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type RemoveIndexSignature<T> = {
  [
    K in keyof T
      as K extends `${infer S}`
      ? S
      : never
  ]: T[K]
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

ccbabi avatar Mar 09 '22 02:03 ccbabi

  1. 解法1
interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

type RemoveIndexSignature<T> = {
  [K in keyof T as (string extends K ? never : number extends K ? never : K)]: T[K]
}
  1. 根据上文答案修改
interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

type RemoveIndexSignature<T> = {
  [P in keyof T as P extends `${infer String}` ? P : never]: T[P]
}

通过[P extends ${infer Str}]可以区分到底是string类型还是string字面量类型

type A = 'bar' extends `${infer R}` ? true : false // true
type B = string extends `${infer R}` ? true : false  // false

waleiwalei avatar Mar 16 '22 04:03 waleiwalei

索引一般是 string衍生的属性名,而可索引签名不是,可以根据这个来过滤掉可索引签名:

interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type RemoveIndexSignature<T extends object> = {
    [K in keyof T as K  extends `${infer Str}`? Str : never] : T[K]
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

heweijian4933 avatar Jun 03 '22 03:06 heweijian4933

//question
// 实现一个 RemoveIndexSignature 工具类型,用于移除已有类型中的索引签名。具体的使用示例如下所示:
// interface Foo {
//   [key: string]: any;
//   [key: number]: any;
//   bar(): void;
// }
// type RemoveIndexSignature<T> = // 你的实现代码
// type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

//answer
type RemoveIndexSignature<T> = {
  [K in keyof T as string extends K ? never : number extends K ? never : symbol extends K ? never : K]: T[K]
}
interface Foo {
  [key: string]: any
  [key: number]: any
  bar(): void
}
type FooWithOnlyBar = RemoveIndexSignature<Foo>

ChuTingzj avatar Jun 06 '22 13:06 ChuTingzj

type RemoveIndexSignature<T> = { [K in keyof T as K extends T[K] ? never : K]: T[K]; };

itcast-e avatar Aug 19 '22 09:08 itcast-e

你这个把 any 都去掉了 如果是 interface Foo { [key: string]: any; [key: number]: any; bar(): void; o: any; } o 不也没了吗

zhengyimeng avatar Nov 11 '22 03:11 zhengyimeng

type RemoveIndexSignature<T> = {
    [P in keyof T as string extends P ? never : (number extends P ? never : P)] : T[P]
}

zhixiaotong avatar Feb 03 '23 02:02 zhixiaotong

interface Foo {
  [key: string]: any;
  [key: number]: any;
  bar(): void;
}

type RemoveIndexSignature<T> = {
  [K in keyof T as (string extends K ? never : number extends K ? never : K)]: T[K]
}

type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }

SweeperDuan avatar Dec 12 '23 06:12 SweeperDuan