Skip to content

Commit

Permalink
Be more permissive with readonly input types (#20)
Browse files Browse the repository at this point in the history
* Be more permissive with readonly input types

* Fixes
  • Loading branch information
jridgewell committed Oct 8, 2022
1 parent d58ae00 commit ca19cc6
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 6 deletions.
5 changes: 3 additions & 2 deletions src/any-map.ts
Expand Up @@ -12,6 +12,7 @@ import type {
SectionedSourceMap,
DecodedSourceMap,
SectionedSourceMapInput,
Ro,
} from './types';
import type { SourceMapSegment } from './sourcemap-segment';

Expand Down Expand Up @@ -46,7 +47,7 @@ export const AnyMap: AnyMap = function (map, mapUrl) {
} as AnyMap;

function recurse(
input: SectionedSourceMap,
input: Ro<SectionedSourceMap>,
mapUrl: string | null | undefined,
mappings: SourceMapSegment[][],
sources: string[],
Expand Down Expand Up @@ -90,7 +91,7 @@ function recurse(
}

function addSection(
input: Section['map'],
input: Ro<Section['map']>,
mapUrl: string | null | undefined,
mappings: SourceMapSegment[][],
sources: string[],
Expand Down
2 changes: 1 addition & 1 deletion src/trace-mapping.ts
Expand Up @@ -159,7 +159,7 @@ export class TraceMap implements SourceMap {

if (!isString && (map as unknown as { _decodedMemo: any })._decodedMemo) return map as TraceMap;

const parsed = (isString ? JSON.parse(map) : map) as Exclude<SourceMapInput, string | TraceMap>;
const parsed = (isString ? JSON.parse(map) : map) as DecodedSourceMap | EncodedSourceMap;

const { version, file, names, sourceRoot, sources, sourcesContent } = parsed;
this.version = version;
Expand Down
13 changes: 11 additions & 2 deletions src/types.ts
Expand Up @@ -57,8 +57,9 @@ export type InvalidGeneratedMapping = {

export type Bias = typeof GREATEST_LOWER_BOUND | typeof LEAST_UPPER_BOUND;

export type SourceMapInput = string | EncodedSourceMap | DecodedSourceMap | TraceMap;
export type SectionedSourceMapInput = SourceMapInput | SectionedSourceMap;
export type SourceMapInput = string | Ro<EncodedSourceMap> | Ro<DecodedSourceMap> | TraceMap;

export type SectionedSourceMapInput = SourceMapInput | Ro<SectionedSourceMap>;

export type Needle = { line: number; column: number; bias?: Bias };
export type SourceNeedle = { source: string; line: number; column: number; bias?: Bias };
Expand Down Expand Up @@ -90,3 +91,11 @@ export abstract class SourceMap {
declare sourcesContent: SourceMapV3['sourcesContent'];
declare resolvedSources: SourceMapV3['sources'];
}

export type Ro<T> = T extends Array<infer V>
? V[] | Readonly<V[]> | RoArray<V> | Readonly<RoArray<V>>
: T extends object
? T | Readonly<T> | RoObject<T> | Readonly<RoObject<T>>
: T;
type RoArray<T> = Ro<T>[];
type RoObject<T> = { [K in keyof T]: T[K] | Ro<T[K]> };
19 changes: 18 additions & 1 deletion test/any-map.test.ts
Expand Up @@ -3,7 +3,7 @@
import { test, describe } from './setup';
import { AnyMap, encodedMappings, decodedMappings } from '../src/trace-mapping';

import type { SectionedSourceMap } from '../src/trace-mapping';
import type { SectionedSourceMap, SourceMapSegment } from '../src/trace-mapping';

describe('AnyMap', () => {
const map: SectionedSourceMap = {
Expand Down Expand Up @@ -126,4 +126,21 @@ describe('AnyMap', () => {
]);
});
});

describe('typescript readonly type', () => {
test('decoded source map', (t) => {
// This is a TS lint test, not a real one.
t.pass();

const decodedMap = {
version: 3 as const,
sources: ['input.js'] as readonly string[],
names: [] as readonly string[],
mappings: [] as readonly SourceMapSegment[][],
sourcesContent: [] as readonly string[],
};

new AnyMap(decodedMap);
});
});
});
18 changes: 18 additions & 0 deletions test/trace-mapping.test.ts
Expand Up @@ -24,6 +24,7 @@ import type {
EncodedSourceMap,
DecodedSourceMap,
EachMapping,
SourceMapSegment,
} from '../src/trace-mapping';

describe('TraceMap', () => {
Expand Down Expand Up @@ -462,4 +463,21 @@ describe('TraceMap', () => {
t.is(encodedMappings(tracer), '');
});
});

describe('typescript readonly type', () => {
test('decoded source map', (t) => {
// This is a TS lint test, not a real one.
t.pass();

const decodedMap = {
version: 3 as const,
sources: ['input.js'] as readonly string[],
names: [] as readonly string[],
mappings: [] as readonly SourceMapSegment[][],
sourcesContent: [] as readonly string[],
};

new TraceMap(decodedMap);
});
});
});

0 comments on commit ca19cc6

Please sign in to comment.