Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 0 additions & 60 deletions eslint-suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2008,41 +2008,11 @@
"count": 1
}
},
"packages/utils/src/assert.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"packages/utils/src/caip-types.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 4
}
},
"packages/utils/src/collections.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 2
}
},
"packages/utils/src/collections.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 2
}
},
"packages/utils/src/errors.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 3
}
},
"packages/utils/src/errors.ts": {
"no-restricted-syntax": {
"count": 3
}
},
"packages/utils/src/fs.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 20
}
},
"packages/utils/src/fs.ts": {
"jsdoc/require-returns": {
"count": 1
Expand All @@ -2058,31 +2028,6 @@
"count": 3
}
},
"packages/utils/src/json.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"packages/utils/src/json.tst.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"packages/utils/src/logging.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 2
}
},
"packages/utils/src/misc.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"packages/utils/src/misc.tst.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"packages/utils/src/mnemonic.ts": {
"jsdoc/tag-lines": {
"count": 1
Expand All @@ -2092,10 +2037,5 @@
"jsdoc/tag-lines": {
"count": 1
}
},
"packages/utils/src/unitsConversion.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 29
}
}
}
3 changes: 3 additions & 0 deletions packages/utils/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Narrowed three public type signatures from `any` to `unknown` ([#10249](https://github.com/MetaMask/core/pull/10249))
- `assert` now accepts `value: unknown`, `FrozenMap.forEach` and `FrozenSet.forEach` now accept `thisArg?: unknown`, and `getKnownPropertyNames` now accepts `Partial<Record<Key, unknown>>`.
- This is not a breaking change. `unknown` accepts every value that `any` did, so no call site needs to change.
- This package was migrated from `MetaMask/utils` to the `MetaMask/core` monorepo ([#10175](https://github.com/MetaMask/core/pull/10175))
- See [MetaMask/utils](https://github.com/MetaMask/utils/blob/main/CHANGELOG.md) for the original changelog, which covers every release up to and including `12.0.0`.

Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class AssertionError extends Error {
* the `message` argument, this argument is ignored.
*/
export function assert(
value: any,
value: unknown,
message: string | Error = 'Assertion failed.',
ErrorWrapper: AssertionErrorConstructor = AssertionError,
): asserts value {
Expand Down
14 changes: 10 additions & 4 deletions packages/utils/src/caip-types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ import {
toCaipAssetType,
toCaipChainId,
} from './caip-types.js';
import type {
CaipAccountId,
CaipAssetId,
CaipAssetType,
CaipChainId,
} from './caip-types.js';

describe('isCaipChainId', () => {
it.each(CAIP_CHAIN_ID_FIXTURES)(
Expand Down Expand Up @@ -326,7 +332,7 @@ describe('parseCaipChainId', () => {
'foo:',
'foo:foobarbazquzfoobarbazquzfoobarbazquzfoobarbazquzfoobarbazquzfoobarbazquz',
])('throws for invalid input %s', (input) => {
expect(() => parseCaipChainId(input as any)).toThrow(
expect(() => parseCaipChainId(input as CaipChainId)).toThrow(
'Invalid CAIP chain ID.',
);
});
Expand Down Expand Up @@ -406,7 +412,7 @@ describe('parseCaipAccountId', () => {
'eip155:1',
'eip155:1:',
])('throws for invalid input %s', (input) => {
expect(() => parseCaipAccountId(input as any)).toThrow(
expect(() => parseCaipAccountId(input as CaipAccountId)).toThrow(
'Invalid CAIP account ID.',
);
});
Expand Down Expand Up @@ -483,7 +489,7 @@ describe('parseCaipAssetType', () => {
'eip155:1',
'eip155:1:',
])('throws for invalid input %s', (input) => {
expect(() => parseCaipAssetType(input as any)).toThrow(
expect(() => parseCaipAssetType(input as CaipAssetType)).toThrow(
'Invalid CAIP asset type.',
);
});
Expand Down Expand Up @@ -536,7 +542,7 @@ describe('parseCaipAssetId', () => {
'eip155:1',
'eip155:1:',
])('throws for invalid input %s', (input) => {
expect(() => parseCaipAssetId(input as any)).toThrow(
expect(() => parseCaipAssetId(input as CaipAssetId)).toThrow(
'Invalid CAIP asset ID.',
);
});
Expand Down
6 changes: 4 additions & 2 deletions packages/utils/src/collections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ describe('FrozenMap', () => {
});

it('is frozen and cannot be mutated', () => {
const frozenMap: any = new FrozenMap();
// Cast so the absent mutation methods can be probed for at runtime.
const frozenMap = new FrozenMap() as unknown as Record<string, unknown>;
expect(frozenMap.set).toBeUndefined();
expect(frozenMap.clear).toBeUndefined();

Expand Down Expand Up @@ -247,7 +248,8 @@ describe('FrozenSet', () => {
});

it('is frozen and cannot be mutated', () => {
const frozenSet: any = new FrozenSet();
// Cast so the absent mutation methods can be probed for at runtime.
const frozenSet = new FrozenSet() as unknown as Record<string, unknown>;
expect(frozenSet.set).toBeUndefined();
expect(frozenSet.clear).toBeUndefined();

Expand Down
4 changes: 2 additions & 2 deletions packages/utils/src/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class FrozenMap<Key, Value> implements ReadonlyMap<Key, Value> {

public forEach(
callbackfn: (value: Value, key: Key, map: this) => void,
thisArg?: any,
thisArg?: unknown,
): void {
// We have to wrap the specified callback in order to prevent it from
// receiving a reference to the inner map.
Expand Down Expand Up @@ -98,7 +98,7 @@ class FrozenSet<Value> implements ReadonlySet<Value> {

public forEach(
callbackfn: (value: Value, value2: Value, set: this) => void,
thisArg?: any,
thisArg?: unknown,
): void {
// We have to wrap the specified callback in order to prevent it from
// receiving a reference to the inner set.
Expand Down
6 changes: 3 additions & 3 deletions packages/utils/src/errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ describe('wrapError', () => {
let originalError;
try {
await fs.promises.readFile('/tmp/nonexistent', 'utf8');
} catch (error: any) {
} catch (error) {
originalError = error;
}

Expand All @@ -142,7 +142,7 @@ describe('wrapError', () => {
let originalError;
try {
await fs.promises.readFile('/tmp/nonexistent', 'utf8');
} catch (error: any) {
} catch (error) {
originalError = error;
}

Expand All @@ -155,7 +155,7 @@ describe('wrapError', () => {
let originalError;
try {
await fs.promises.readFile('/tmp/nonexistent', 'utf8');
} catch (error: any) {
} catch (error) {
originalError = error;
}

Expand Down
52 changes: 12 additions & 40 deletions packages/utils/src/fs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,8 @@ describe('fs', () => {

await withinSandbox(async (sandbox) => {
const filePath = path.join(sandbox.directoryPath, 'test.json');
const stringifier = {
stringify(
json: any,
replacer?:
| ((this: any, key: string, value: any) => any)
| (number | string)[]
| null,
space?: string,
): string {
const stringifier: { stringify: typeof JSON.stringify } = {
stringify(json, replacer, space) {
return (
`${util.inspect(json)}\n` +
`replacer: ${util.inspect(replacer)}, space: ${util.inspect(
Expand All @@ -290,15 +283,8 @@ describe('fs', () => {

await withinSandbox(async (sandbox) => {
const filePath = path.join(sandbox.directoryPath, 'test.json');
const stringifier = {
stringify(
json: any,
replacer?:
| ((this: any, key: string, value: any) => any)
| (number | string)[]
| null,
space?: string,
): string {
const stringifier: { stringify: typeof JSON.stringify } = {
stringify(json, replacer, space) {
return (
`${util.inspect(json)}\n` +
`replacer: ${util.inspect(replacer)}, space: ${util.inspect(
Expand All @@ -325,15 +311,8 @@ describe('fs', () => {

await withinSandbox(async (sandbox) => {
const filePath = path.join(sandbox.directoryPath, 'test.json');
const stringifier = {
stringify(
json: any,
replacer?:
| ((this: any, key: string, value: any) => any)
| (number | string)[]
| null,
space?: string,
): string {
const stringifier: { stringify: typeof JSON.stringify } = {
stringify(json, replacer, space) {
return (
`${util.inspect(json)}\n` +
`replacer: ${util.inspect(replacer)}, space: ${util.inspect(
Expand Down Expand Up @@ -362,15 +341,8 @@ describe('fs', () => {
// Make sandbox root directory non-readable
await fs.promises.chmod(sandbox.directoryPath, 0o600);
const filePath = path.join(sandbox.directoryPath, 'test.json');
const stringifier = {
stringify(
json: any,
replacer?:
| ((this: any, key: string, value: any) => any)
| (number | string)[]
| null,
space?: string,
): string {
const stringifier: { stringify: typeof JSON.stringify } = {
stringify(json, replacer, space) {
return (
`${util.inspect(json)}\n` +
`replacer: ${util.inspect(replacer)}, space: ${util.inspect(
Expand Down Expand Up @@ -435,7 +407,7 @@ describe('fs', () => {

it('re-throws a wrapped version of any error that occurs, assigning it the same code and giving it a stack', async () => {
const entryPath = '/some/file';
const error: any = new Error('oops');
const error: Error & { code?: string } = new Error('oops');
error.code = 'ESOMETHING';
error.stack = 'some stack';
when(jest.spyOn(fs.promises, 'stat'))
Expand Down Expand Up @@ -494,7 +466,7 @@ describe('fs', () => {

it('re-throws a wrapped version of any error that occurs, assigning it the same code and giving it a stack', async () => {
const entryPath = '/some/file';
const error: any = new Error('oops');
const error: Error & { code?: string } = new Error('oops');
error.code = 'ESOMETHING';
error.stack = 'some stack';
when(jest.spyOn(fs.promises, 'stat'))
Expand Down Expand Up @@ -604,7 +576,7 @@ describe('fs', () => {

it('re-throws a wrapped version of any error that occurs, assigning it the same code and giving it a stack', async () => {
const filePath = '/some/file';
const error: any = new Error('oops');
const error: Error & { code?: string } = new Error('oops');
error.code = 'ESOMETHING';
error.stack = 'some stack';
when(jest.spyOn(fs.promises, 'rm'))
Expand Down Expand Up @@ -655,7 +627,7 @@ describe('fs', () => {

it('re-throws a wrapped version of any error that occurs, assigning it the same code and giving it a stack', async () => {
const directoryPath = '/some/directory';
const error: any = new Error('oops');
const error: Error & { code?: string } = new Error('oops');
error.code = 'ESOMETHING';
error.stack = 'some stack';
when(jest.spyOn(fs.promises, 'rm'))
Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ export const JsonRpcRequestStruct = object({
});

export type InferWithParams<
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- `Struct<any>` is superstruct's idiom for "any struct". `Struct<unknown>` does not work: `Struct` holds `refiner` as a property, which puts the value type in a contravariant position, so no concrete struct satisfies the constraint.
Type extends Struct<any>,
Params extends JsonRpcParams,
> = Infer<Type> & {
Expand Down
1 change: 1 addition & 0 deletions packages/utils/src/json.tst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ describe('Json', () => {
test('has known edge cases', () => {
// The Json type doesn't protect against the `any` type. Passing `any`
// explicitly is the point of the test, so it must not be removed.
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- The `any` under test cannot be replaced without inverting what this assertion checks.
expect<any>().type.toBeAssignableTo<Json>();

// The Json type gets confused by interfaces. This interface is valid Json,
Expand Down
4 changes: 2 additions & 2 deletions packages/utils/src/logging.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('logging', () => {
log.enabled = true;
// Typecast: The Debugger type is wrong and does not include a `useColors`
// property.
(log as any).useColors = false;
(log as unknown as { useColors: boolean }).useColors = false;

log('Some message');

Expand All @@ -38,7 +38,7 @@ describe('logging', () => {
log.enabled = true;
// Typecast: The Debugger type is wrong and does not include a `useColors`
// property.
(log as any).useColors = false;
(log as unknown as { useColors: boolean }).useColors = false;

log('Some message');

Expand Down
2 changes: 1 addition & 1 deletion packages/utils/src/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export const hasProperty = <
* derived from the object itself.
*/
export function getKnownPropertyNames<Key extends PropertyKey>(
object: Partial<Record<Key, any>>,
object: Partial<Record<Key, unknown>>,
): Key[] {
return Object.getOwnPropertyNames(object) as Key[];
}
Expand Down
4 changes: 3 additions & 1 deletion packages/utils/src/misc.tst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ describe('hasProperty', () => {
exampleErrorWithCode.code = 999;

// Establish that trying to check for a custom property on an error results in failure
expect(exampleErrorWithCode).type.not.toBeAssignableTo<{ code: any }>();
expect(exampleErrorWithCode).type.not.toBeAssignableTo<{
code: unknown;
}>();

if (hasProperty(exampleErrorWithCode, 'code')) {
expect(exampleErrorWithCode.code).type.toBe<unknown>();
Expand Down
Loading