/
githubmirror
/
TypeScript
Обзор
Документация
Войти
/
githubmirror
/
TypeScript
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/deprecatedCompat/deprecations.ts
152 строки
6 KB
Lars Kappert
Remove unused exports & dead code (using Knip) (#56817)
28 июн 2024, 00:24
Не верифицирован
28 июн 2024, 00:24
752135e
Код
Авторство
О чём код?
import { hasProperty, UnionToIntersection, Version, } from "./_namespaces/ts.js"; import { deprecate } from "./deprecate.js"; /** @internal */ export interface DeprecationOptions { message?: string; error?: boolean; since?: Version | string; warnAfter?: Version | string; errorAfter?: Version | string; typeScriptVersion?: Version | string; name?: string; } // The following are deprecations for the public API. Deprecated exports are removed from the compiler itself // and compatible implementations are added here, along with an appropriate deprecation warning using // the `@deprecated` JSDoc tag as well as the `deprecate` API. // // Deprecations fall into one of three categories: // // - "soft" - Soft deprecations are indicated with the `@deprecated` JSDoc Tag. // - "warn" - Warning deprecations are indicated with the `@deprecated` JSDoc Tag and a diagnostic message (assuming a compatible host). // - "error" - Error deprecations are either indicated with the `@deprecated` JSDoc tag and will throw a `TypeError` when invoked, or removed from the API entirely. // // Once we have determined enough time has passed after a deprecation has been marked as `"warn"` or `"error"`, it will be removed from the public API. /** * Defines a list of overloads by ordinal * * @internal */ export type OverloadDefinitions = { readonly [P in number]: (...args: any[]) => any; }; /** A function that returns the ordinal of the overload that matches the provided arguments */ type OverloadBinder<T extends OverloadDefinitions> = (args: OverloadParameters<T>) => OverloadKeys<T> | undefined; /** * Extracts the ordinals from an set of overload definitions. * * @internal */ export type OverloadKeys<T extends OverloadDefinitions> = Extract<keyof T, number>; /** * Extracts a union of the potential parameter lists for each overload. * * @internal */ export type OverloadParameters<T extends OverloadDefinitions> = Parameters<{ [P in OverloadKeys<T>]: T[P]; }[OverloadKeys<T>]>; // NOTE: the following doesn't work in TS 4.4 (the current LKG in main), so we have to use UnionToIntersection for now // type OverloadFunction<T extends OverloadDefinitions, R extends ((...args: any[]) => any)[] = [], O = unknown> = // R["length"] extends keyof T ? OverloadFunction<T, [...R, T[R["length"]]], O & T[R["length"]]> : // unknown extends O ? never : O; /** * Constructs an intersection of each overload in a set of overload definitions. * * @internal */ export type OverloadFunction<T extends OverloadDefinitions> = UnionToIntersection<T[keyof T]>; /** * Maps each ordinal in a set of overload definitions to a function that can be used to bind its arguments. * * @internal */ export type OverloadBinders<T extends OverloadDefinitions> = { [P in OverloadKeys<T>]: (args: OverloadParameters<T>) => boolean | undefined; }; /** * Defines deprecations for specific overloads by ordinal. * * @internal */ export type OverloadDeprecations<T extends OverloadDefinitions> = { [P in OverloadKeys<T>]?: DeprecationOptions; }; /** @internal @knipignore */ export function createOverload<T extends OverloadDefinitions>(name: string, overloads: T, binder: OverloadBinders<T>, deprecations?: OverloadDeprecations<T>) { Object.defineProperty(call, "name", { ...Object.getOwnPropertyDescriptor(call, "name"), value: name }); if (deprecations) { for (const key of Object.keys(deprecations)) { const index = +key as (keyof T & number); if (!isNaN(index) && hasProperty(overloads, `${index}`)) { overloads[index] = deprecate(overloads[index], { ...deprecations[index], name }); } } } const bind = createBinder(overloads, binder); return call as OverloadFunction<T>; function call(...args: OverloadParameters<T>) { const index = bind(args); const fn = index !== undefined ? overloads[index] : undefined; if (typeof fn === "function") { return fn(...args); } throw new TypeError("Invalid arguments"); } } function createBinder<T extends OverloadDefinitions>(overloads: T, binder: OverloadBinders<T>): OverloadBinder<T> { return args => { for (let i = 0; hasProperty(overloads, `${i}`) && hasProperty(binder, `${i}`); i++) { const fn = binder[i]; if (fn(args)) { return i as OverloadKeys<T>; } } }; } /** @internal */ export interface OverloadBuilder { overload<T extends OverloadDefinitions>(overloads: T): BindableOverloadBuilder<T>; } /** @internal */ export interface BindableOverloadBuilder<T extends OverloadDefinitions> { bind(binder: OverloadBinders<T>): BoundOverloadBuilder<T>; } /** @internal */ export interface FinishableOverloadBuilder<T extends OverloadDefinitions> { finish(): OverloadFunction<T>; } /** @internal */ export interface BoundOverloadBuilder<T extends OverloadDefinitions> extends FinishableOverloadBuilder<T> { deprecate(deprecations: OverloadDeprecations<T>): FinishableOverloadBuilder<T>; } // NOTE: We only use this "builder" because we don't infer correctly when calling `createOverload` directly in < TS 4.7, // but lib is currently at TS 4.4. We can switch to directly calling `createOverload` when we update LKG in main. /** @internal @knipignore */ export function buildOverload(name: string): OverloadBuilder { return { overload: overloads => ({ bind: binder => ({ finish: () => createOverload(name, overloads, binder), deprecate: deprecations => ({ finish: () => createOverload(name, overloads, binder, deprecations), }), }), }), }; }