index.d.ts 4.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. type Intrinsic = typeof globalThis;
  2. type IntrinsicName = keyof Intrinsic | `%${keyof Intrinsic}%`;
  3. type IntrinsicPath = IntrinsicName | `${StripPercents<IntrinsicName>}.${string}` | `%${StripPercents<IntrinsicName>}.${string}%`;
  4. type AllowMissing = boolean;
  5. type StripPercents<T extends string> = T extends `%${infer U}%` ? U : T;
  6. type BindMethodPrecise<F> =
  7. F extends (this: infer This, ...args: infer Args) => infer R
  8. ? (obj: This, ...args: Args) => R
  9. : F extends {
  10. (this: infer This1, ...args: infer Args1): infer R1;
  11. (this: infer This2, ...args: infer Args2): infer R2
  12. }
  13. ? {
  14. (obj: This1, ...args: Args1): R1;
  15. (obj: This2, ...args: Args2): R2
  16. }
  17. : never
  18. // Extract method type from a prototype
  19. type GetPrototypeMethod<T extends keyof typeof globalThis, M extends string> =
  20. (typeof globalThis)[T] extends { prototype: any }
  21. ? M extends keyof (typeof globalThis)[T]['prototype']
  22. ? (typeof globalThis)[T]['prototype'][M]
  23. : never
  24. : never
  25. // Get static property/method
  26. type GetStaticMember<T extends keyof typeof globalThis, P extends string> =
  27. P extends keyof (typeof globalThis)[T] ? (typeof globalThis)[T][P] : never
  28. // Type that maps string path to actual bound function or value with better precision
  29. type BoundIntrinsic<S extends string> =
  30. S extends `${infer Obj}.prototype.${infer Method}`
  31. ? Obj extends keyof typeof globalThis
  32. ? BindMethodPrecise<GetPrototypeMethod<Obj, Method & string>>
  33. : unknown
  34. : S extends `${infer Obj}.${infer Prop}`
  35. ? Obj extends keyof typeof globalThis
  36. ? GetStaticMember<Obj, Prop & string>
  37. : unknown
  38. : unknown
  39. declare function arraySlice<T>(array: readonly T[], start?: number, end?: number): T[];
  40. declare function arraySlice<T>(array: ArrayLike<T>, start?: number, end?: number): T[];
  41. declare function arraySlice<T>(array: IArguments, start?: number, end?: number): T[];
  42. // Special cases for methods that need explicit typing
  43. interface SpecialCases {
  44. '%Object.prototype.isPrototypeOf%': (thisArg: {}, obj: unknown) => boolean;
  45. '%String.prototype.replace%': {
  46. (str: string, searchValue: string | RegExp, replaceValue: string): string;
  47. (str: string, searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string
  48. };
  49. '%Object.prototype.toString%': (obj: {}) => string;
  50. '%Object.prototype.hasOwnProperty%': (obj: {}, v: PropertyKey) => boolean;
  51. '%Array.prototype.slice%': typeof arraySlice;
  52. '%Array.prototype.map%': <T, U>(array: readonly T[], callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any) => U[];
  53. '%Array.prototype.filter%': <T>(array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any) => T[];
  54. '%Array.prototype.indexOf%': <T>(array: readonly T[], searchElement: T, fromIndex?: number) => number;
  55. '%Function.prototype.apply%': <T, A extends any[], R>(fn: (...args: A) => R, thisArg: any, args: A) => R;
  56. '%Function.prototype.call%': <T, A extends any[], R>(fn: (...args: A) => R, thisArg: any, ...args: A) => R;
  57. '%Function.prototype.bind%': <T, A extends any[], R>(fn: (...args: A) => R, thisArg: any, ...args: A) => (...remainingArgs: A) => R;
  58. '%Promise.prototype.then%': {
  59. <T, R>(promise: Promise<T>, onfulfilled: (value: T) => R | PromiseLike<R>): Promise<R>;
  60. <T, R>(promise: Promise<T>, onfulfilled: ((value: T) => R | PromiseLike<R>) | undefined | null, onrejected: (reason: any) => R | PromiseLike<R>): Promise<R>;
  61. };
  62. '%RegExp.prototype.test%': (regexp: RegExp, str: string) => boolean;
  63. '%RegExp.prototype.exec%': (regexp: RegExp, str: string) => RegExpExecArray | null;
  64. '%Error.prototype.toString%': (error: Error) => string;
  65. '%TypeError.prototype.toString%': (error: TypeError) => string;
  66. '%String.prototype.split%': (
  67. obj: unknown,
  68. splitter: string | RegExp | {
  69. [Symbol.split](string: string, limit?: number): string[];
  70. },
  71. limit?: number | undefined
  72. ) => string[];
  73. }
  74. /**
  75. * Returns a bound function for a prototype method, or a value for a static property.
  76. *
  77. * @param name - The name of the intrinsic (e.g. 'Array.prototype.slice')
  78. * @param {AllowMissing} [allowMissing] - Whether to allow missing intrinsics (default: false)
  79. */
  80. declare function callBound<K extends keyof SpecialCases | StripPercents<keyof SpecialCases>, S extends IntrinsicPath>(name: K, allowMissing?: AllowMissing): SpecialCases[`%${StripPercents<K>}%`];
  81. declare function callBound<K extends keyof SpecialCases | StripPercents<keyof SpecialCases>, S extends IntrinsicPath>(name: S, allowMissing?: AllowMissing): BoundIntrinsic<S>;
  82. export = callBound;