'Make typescript interface extend another interface excluding keys already defined
For some hacky scripting on my iPhone (not code I would ever write for production), I frequently find myself treating strings as string[] (a character array). Since typing on a phone is significantly slower than on a keyboard and characters are at a premium given the 57-character-wide screen size, I wrote some code that takes every method of Array.prototype, maps it to Array.from(this)[fn], and attaches it to String.prototype if it does not already exist. For example, I want .slice() still to return a string, not a string[].
Object.entries(
Object.getOwnPropertyDescriptors(Array.prototype)
)
.filter(([n, d]) =>
!(n in String.prototype) &&
typeof d.value === 'function'
)
.forEach(([n]) =>
String.prototype[n] = function (...args) {
return Array.from(this)[n](...args)
}
)
Now I can run 'abc'.filter(x => x !== 'b') and receive ['a', 'c']. Huzzah.
Now I want to write the updated interface String without manually copying over every valid declaration from Array<T>. (Sometimes play.js will read a .d.ts file.)
My best attempt introduces circular type references, which doesn't surprise me.
type MethodNames<T> = {
[K in keyof T & string]: T[K] extends (...args: any[]) => any ? K : never;
}[keyof T & string];
type MethodsOf<T> = {
[K in MethodNames<T>]: T[K];
};
type CharArray = Omit<MethodsOf<Array<string>>, keyof string>;
declare global {
interface String extends CharArray {}
}
export {};
Up until I make String extend CharArray, everything works fine. CharArray has the proper methods. Once I add the extension, CharArray tries to exclude its own members, since those members are now members of String.
Is what I'm asking even possible? I suspect the answer is no, but I thought I would ask.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
