awesome-typescript
awesome-typescript copied to clipboard
「重学TS 2.0 」TS 练习题第二十三题
实现一个 RemoveIndexSignature 工具类型,用于移除已有类型中的索引签名。具体的使用示例如下所示:
interface Foo {
[key: string]: any;
[key: number]: any;
bar(): void;
}
type RemoveIndexSignature<T> = // 你的实现代码
type FooWithOnlyBar = RemoveIndexSignature<Foo>; //{ bar: () => void; }
请在下面评论你的答案。
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; }
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; }
type RemoveIndexSignature<T> = {
[key in keyof T as symbol extends key? never
: `${any}` extends key? never
: number extends key? never
: key]: T[key];
};
// 实现一个 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的判断过滤
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; }
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; }
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; }
- 解法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]
}
- 根据上文答案修改
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
索引一般是
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; }
//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>
type RemoveIndexSignature<T> = { [K in keyof T as K extends T[K] ? never : K]: T[K]; };
你这个把 any 都去掉了 如果是 interface Foo { [key: string]: any; [key: number]: any; bar(): void; o: any; } o 不也没了吗
type RemoveIndexSignature<T> = {
[P in keyof T as string extends P ? never : (number extends P ? never : P)] : T[P]
}
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; }