Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable @typescript-eslint/no-redundant-type-constituents rule #15794

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ module.exports = [
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-misused-promises": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-redundant-type-constituents": "off",
"@typescript-eslint/no-this-alias": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
Expand Down
5 changes: 1 addition & 4 deletions packages/babel-cli/src/babel-external-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import commander from "commander";
import { buildExternalHelpers } from "@babel/core";

function collect(
value: string | any,
previousValue: Array<string>,
): Array<string> {
function collect(value: unknown, previousValue: Array<string>): Array<string> {
// If the user passed the option with no value, like "babel-external-helpers --whitelist", do nothing.
if (typeof value !== "string") return previousValue;

Expand Down
3 changes: 2 additions & 1 deletion packages/babel-cli/src/babel/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { CmdOptions } from "./options";
import * as watcher from "./watcher";

import type {
EncodedSourceMap,
SectionedSourceMap,
SourceMapInput,
TraceMap,
Expand Down Expand Up @@ -40,7 +41,7 @@ export default async function ({

mapSections.push({
offset: { line: offset, column: 0 },
map: result.map || {
map: (result.map as EncodedSourceMap) || {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cast is unfortunate because the EncodedSourceMap in trace-mapping

export interface SourceMapV3 {
    file?: string | null;
    names: string[];
    sourceRoot?: string;
    sources: (string | null)[];
    sourcesContent?: (string | null)[];
    version: 3;
}
export interface EncodedSourceMap extends SourceMapV3 {
    mappings: string;
}

is slightly different to the one in gen-mapping.

export interface SourceMapV3 {
    file?: string | null;
    names: readonly string[];
    sourceRoot?: string;
    sources: readonly (string | null)[];
    sourcesContent?: readonly (string | null)[];
    version: 3;
}
export interface EncodedSourceMap extends SourceMapV3 {
    mappings: string;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jridgewell Maybe you want to align them

version: 3,
names: [],
sources: [],
Expand Down
9 changes: 4 additions & 5 deletions packages/babel-cli/src/babel/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,9 @@ export default function parseArgv(args: Array<string>): CmdOptions | null {
};
}

function booleanify(val: any): boolean | any {
function booleanify(val: "false" | 0 | ""): false;
function booleanify(val: "true" | 1): true;
function booleanify(val: any): any {
if (val === undefined) return undefined;

if (val === "true" || val == 1) {
Expand All @@ -373,10 +375,7 @@ function booleanify(val: any): boolean | any {
return val;
}

function collect(
value: string | any,
previousValue: Array<string>,
): Array<string> {
function collect(value: unknown, previousValue: Array<string>): Array<string> {
// If the user passed the option with no value, like "babel file.js --presets", do nothing.
if (typeof value !== "string") return previousValue;

Expand Down
13 changes: 7 additions & 6 deletions packages/babel-core/src/config/config-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type { ReadonlyDeepArray } from "./helpers/deep-array";

import { endHiddenCallStack } from "../errors/rewrite-stack-trace";
import ConfigError from "../errors/config-error";
import type { PluginAPI, PresetAPI } from "./helpers/config-api";

const debug = buildDebug("babel:config:config-chain");

Expand All @@ -42,8 +43,8 @@ import type {
} from "./config-descriptors";

export type ConfigChain = {
plugins: Array<UnloadedDescriptor>;
presets: Array<UnloadedDescriptor>;
plugins: Array<UnloadedDescriptor<PluginAPI>>;
presets: Array<UnloadedDescriptor<PresetAPI>>;
options: Array<ValidatedOptions>;
files: Set<string>;
};
Expand Down Expand Up @@ -760,12 +761,12 @@ function normalizeOptions(opts: ValidatedOptions): ValidatedOptions {
return options;
}

function dedupDescriptors(
items: Array<UnloadedDescriptor>,
): Array<UnloadedDescriptor> {
function dedupDescriptors<API>(
items: Array<UnloadedDescriptor<API>>,
): Array<UnloadedDescriptor<API>> {
const map: Map<
Function,
Map<string | void, { value: UnloadedDescriptor }>
Map<string | void, { value: UnloadedDescriptor<API> }>
> = new Map();

const descriptors = [];
Expand Down
43 changes: 22 additions & 21 deletions packages/babel-core/src/config/config-descriptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,36 @@ import type {
} from "./validation/options";

import { resolveBrowserslistConfigFile } from "./resolve-targets";
import type { PluginAPI, PresetAPI } from "./helpers/config-api";

// Represents a config object and functions to lazily load the descriptors
// for the plugins and presets so we don't load the plugins/presets unless
// the options object actually ends up being applicable.
export type OptionsAndDescriptors = {
options: ValidatedOptions;
plugins: () => Handler<Array<UnloadedDescriptor>>;
presets: () => Handler<Array<UnloadedDescriptor>>;
plugins: () => Handler<Array<UnloadedDescriptor<PluginAPI>>>;
presets: () => Handler<Array<UnloadedDescriptor<PresetAPI>>>;
};

// Represents a plugin or presets at a given location in a config object.
// At this point these have been resolved to a specific object or function,
// but have not yet been executed to call functions with options.
export type UnloadedDescriptor = {
export interface UnloadedDescriptor<API, Options = {} | undefined | false> {
name: string | undefined;
value: any | Function;
options: {} | undefined | false;
value: object | ((api: API, options: Options, dirname: string) => unknown);
options: Options;
dirname: string;
alias: string;
ownPass?: boolean;
file?: {
request: string;
resolved: string;
};
};
}

function isEqualDescriptor(
a: UnloadedDescriptor,
b: UnloadedDescriptor,
function isEqualDescriptor<API>(
a: UnloadedDescriptor<API>,
b: UnloadedDescriptor<API>,
): boolean {
return (
a.name === b.name &&
Expand Down Expand Up @@ -150,7 +151,7 @@ const createCachedPresetDescriptors = makeWeakCacheSync(
return makeStrongCacheSync((alias: string) =>
makeStrongCache(function* (
passPerPreset: boolean,
): Handler<Array<UnloadedDescriptor>> {
): Handler<Array<UnloadedDescriptor<PresetAPI>>> {
const descriptors = yield* createPresetDescriptors(
items,
dirname,
Expand All @@ -174,7 +175,7 @@ const createCachedPluginDescriptors = makeWeakCacheSync(
const dirname = cache.using(dir => dir);
return makeStrongCache(function* (
alias: string,
): Handler<Array<UnloadedDescriptor>> {
): Handler<Array<UnloadedDescriptor<PluginAPI>>> {
const descriptors = yield* createPluginDescriptors(items, dirname, alias);
return descriptors.map(
// Items are cached using the overall plugin array identity when
Expand All @@ -197,9 +198,9 @@ const DEFAULT_OPTIONS = {};
* cache, or else returns the input descriptor and adds it to the cache for
* next time.
*/
function loadCachedDescriptor(
cache: WeakMap<{} | Function, WeakMap<{}, Array<UnloadedDescriptor>>>,
desc: UnloadedDescriptor,
function loadCachedDescriptor<API>(
cache: WeakMap<{} | Function, WeakMap<{}, Array<UnloadedDescriptor<API>>>>,
desc: UnloadedDescriptor<API>,
) {
const { value, options = DEFAULT_OPTIONS } = desc;
if (options === false) return desc;
Expand Down Expand Up @@ -235,7 +236,7 @@ function* createPresetDescriptors(
dirname: string,
alias: string,
passPerPreset: boolean,
): Handler<Array<UnloadedDescriptor>> {
): Handler<Array<UnloadedDescriptor<PresetAPI>>> {
return yield* createDescriptors(
"preset",
items,
Expand All @@ -249,17 +250,17 @@ function* createPluginDescriptors(
items: PluginList,
dirname: string,
alias: string,
): Handler<Array<UnloadedDescriptor>> {
): Handler<Array<UnloadedDescriptor<PluginAPI>>> {
return yield* createDescriptors("plugin", items, dirname, alias);
}

function* createDescriptors(
function* createDescriptors<API>(
type: "plugin" | "preset",
items: PluginList,
dirname: string,
alias: string,
ownPass?: boolean,
): Handler<Array<UnloadedDescriptor>> {
): Handler<Array<UnloadedDescriptor<API>>> {
const descriptors = yield* gensync.all(
items.map((item, index) =>
createDescriptor(item, dirname, {
Expand All @@ -278,7 +279,7 @@ function* createDescriptors(
/**
* Given a plugin/preset item, resolve it into a standard format.
*/
export function* createDescriptor(
export function* createDescriptor<API>(
pair: PluginItem,
dirname: string,
{
Expand All @@ -290,7 +291,7 @@ export function* createDescriptor(
alias: string;
ownPass?: boolean;
},
): Handler<UnloadedDescriptor> {
): Handler<UnloadedDescriptor<API>> {
const desc = getItemDescriptor(pair);
if (desc) {
return desc;
Expand Down Expand Up @@ -365,7 +366,7 @@ export function* createDescriptor(
};
}

function assertNoDuplicates(items: Array<UnloadedDescriptor>): void {
function assertNoDuplicates<API>(items: Array<UnloadedDescriptor<API>>): void {
const map = new Map();

for (const item of items) {
Expand Down
28 changes: 15 additions & 13 deletions packages/babel-core/src/config/full.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,22 @@ export default gensync(function* loadFullConfig(

const presetsDescriptors = presets.map(toDescriptor);
const initialPluginsDescriptors = plugins.map(toDescriptor);
const pluginDescriptorsByPass: Array<Array<UnloadedDescriptor>> = [[]];
const pluginDescriptorsByPass: Array<Array<UnloadedDescriptor<PluginAPI>>> = [
[],
];
const passes: Array<Array<Plugin>> = [];

const externalDependencies: DeepArray<string> = [];

const ignored = yield* enhanceError(
context,
function* recursePresetDescriptors(
rawPresets: Array<UnloadedDescriptor>,
pluginDescriptorsPass: Array<UnloadedDescriptor>,
rawPresets: Array<UnloadedDescriptor<PresetAPI>>,
pluginDescriptorsPass: Array<UnloadedDescriptor<PluginAPI>>,
): Handler<true | void> {
const presets: Array<{
preset: ConfigChain | null;
pass: Array<UnloadedDescriptor>;
pass: Array<UnloadedDescriptor<PluginAPI>>;
}> = [];

for (let i = 0; i < rawPresets.length; i++) {
Expand Down Expand Up @@ -178,7 +180,7 @@ export default gensync(function* loadFullConfig(
passes.push(pass);

for (let i = 0; i < descs.length; i++) {
const descriptor: UnloadedDescriptor = descs[i];
const descriptor = descs[i];
if (descriptor.options !== false) {
try {
// eslint-disable-next-line no-var
Expand Down Expand Up @@ -240,7 +242,7 @@ const makeDescriptorLoader = <Context, API>(
) => API,
) =>
makeWeakCache(function* (
{ value, options, dirname, alias }: UnloadedDescriptor,
{ value, options, dirname, alias }: UnloadedDescriptor<API>,
cache: CacheConfigurator<Context>,
): Handler<LoadedDescriptor> {
// Disabled presets should already have been filtered out
Expand All @@ -250,10 +252,10 @@ const makeDescriptorLoader = <Context, API>(

const externalDependencies: Array<string> = [];

let item = value;
let item: unknown = value;
if (typeof value === "function") {
const factory = maybeAsync(
value,
value as (api: API, options: {}, dirname: string) => unknown,
Copy link
Contributor Author

@JLHwung JLHwung Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish I could get rid of the typing cast here, the typeof check here can not rule out {} completely as it could be Function object.

Suggestions are welcome.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ehoogeveen-medweb My bad. I was meant for object as I typed value as an union of object and a specific function:

value: object | ((api: API, options: Options, dirname: string) => unknown);

but for some reason the typeof check does not rule out the object completely.

`You appear to be using an async plugin/preset, but Babel has been called synchronously`,
);

Expand Down Expand Up @@ -344,7 +346,7 @@ const instantiatePlugin = makeWeakCache(function* (
}

if (plugin.inherits) {
const inheritsDescriptor: UnloadedDescriptor = {
const inheritsDescriptor: UnloadedDescriptor<PluginAPI> = {
name: undefined,
alias: `${alias}$inherits`,
value: plugin.inherits,
Expand Down Expand Up @@ -387,7 +389,7 @@ const instantiatePlugin = makeWeakCache(function* (
* Instantiate a plugin for the given descriptor, returning the plugin/options pair.
*/
function* loadPluginDescriptor(
descriptor: UnloadedDescriptor,
descriptor: UnloadedDescriptor<PluginAPI>,
context: Context.SimplePlugin,
): Handler<Plugin> {
if (descriptor.value instanceof Plugin) {
Expand All @@ -410,7 +412,7 @@ const needsFilename = (val: unknown) => val && typeof val !== "function";

const validateIfOptionNeedsFilename = (
options: ValidatedOptions,
descriptor: UnloadedDescriptor,
descriptor: UnloadedDescriptor<PresetAPI>,
): void => {
if (
needsFilename(options.test) ||
Expand All @@ -435,7 +437,7 @@ const validateIfOptionNeedsFilename = (
const validatePreset = (
preset: PresetInstance,
context: ConfigContext,
descriptor: UnloadedDescriptor,
descriptor: UnloadedDescriptor<PresetAPI>,
): void => {
if (!context.filename) {
const { options } = preset;
Expand Down Expand Up @@ -466,7 +468,7 @@ const instantiatePreset = makeWeakCacheSync(
* Generate a config object that will act as the root of a new nested config.
*/
function* loadPresetDescriptor(
descriptor: UnloadedDescriptor,
descriptor: UnloadedDescriptor<PresetAPI>,
context: Context.FullPreset,
): Handler<{
chain: ConfigChain | null;
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-core/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const createConfigItemAsync = createConfigItemRunner.async;
export function createConfigItem(
target: PluginTarget,
options: Parameters<typeof createConfigItemImpl>[1],
callback?: (err: Error, val: ConfigItem | null) => void,
callback?: (err: Error, val: ConfigItem<PluginAPI> | null) => void,
) {
if (callback !== undefined) {
createConfigItemRunner.errback(target, options, callback);
Expand Down