mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-10-28 16:36:04 +08:00
Merge remote-tracking branch 'origin/main' into release-7.1
This commit is contained in:
commit
3e9236361f
479 files changed
+17066
-94
No files matched your search
@@ -2,11 +2,11 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, main-ts7, ts7-release, 'release-*']
|
||||
branches: [main, main-ts7, ts7-release, 'release-*', 'weswigham/*']
|
||||
pull_request:
|
||||
branches: [main, main-ts7, ts7-release, 'release-*']
|
||||
branches: [main, main-ts7, ts7-release, 'release-*', 'weswigham/*']
|
||||
merge_group:
|
||||
branches: [main, main-ts7, ts7-release, 'release-*']
|
||||
branches: [main, main-ts7, ts7-release, 'release-*', 'weswigham/*']
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -838,8 +838,8 @@ export class API<FromLSP extends boolean = false> implements FormatDiagnosticsHo
|
||||
*
|
||||
* Fetching the snapshot issues a lightweight request to the server to
|
||||
* retrieve its timing collection. Collection must be enabled via the
|
||||
* `collectTiming` option; when it is not, the returned snapshot has
|
||||
* `enabled: false` and zeroed totals.
|
||||
* `collectTiming` option or `TS_API_TIMING_DIR` environment variable; when
|
||||
* it is not, the returned snapshot has `enabled: false` and zeroed totals.
|
||||
*/
|
||||
getTimingInfo(): Promise<TimingInfo> {
|
||||
return this.client.getTimingInfo();
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
TimingCollector,
|
||||
type TimingInfo,
|
||||
} from "../timing.ts";
|
||||
import { TimingDump } from "../timingDump.ts";
|
||||
|
||||
export type { ClientOptions, ClientSocketOptions, ClientSpawnOptions };
|
||||
|
||||
@@ -59,16 +60,22 @@ export class Client {
|
||||
private closed = false;
|
||||
private connecting: Promise<void> | undefined;
|
||||
private timing: TimingCollector | undefined;
|
||||
private timingDump: TimingDump | undefined;
|
||||
private closing: Promise<void> | undefined;
|
||||
private batchedRequests: { method: APIRequest["method"]; params: APIRequest["params"]; resolve: (value: unknown) => void; reject: (reason?: any) => void; }[] = [];
|
||||
private nextBatch: NodeJS.Immediate | "manual" | undefined;
|
||||
|
||||
constructor(options: ClientOptions) {
|
||||
this.timingDump = TimingDump.fromEnvironment("async", isSpawnOptions(options) ? "spawn" : "socket");
|
||||
if (this.timingDump || isSpawnOptions(options) && options.collectTiming) {
|
||||
this.timing = new TimingCollector();
|
||||
}
|
||||
if (this.timingDump && isSpawnOptions(options)) {
|
||||
options = { ...options, collectTiming: true };
|
||||
}
|
||||
this.options = options;
|
||||
if (isSpawnOptions(options)) {
|
||||
configureFileSystemCallbacks(options.fs);
|
||||
if (options.collectTiming) {
|
||||
this.timing = new TimingCollector();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,26 +408,52 @@ export class Client {
|
||||
return this.connection.sendRequest(requestType, undefined);
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
close(): Promise<void> {
|
||||
return this.closing ??= this.closeWorker();
|
||||
}
|
||||
|
||||
private async closeWorker(): Promise<void> {
|
||||
await this.connecting?.catch(() => {}); // if connection is still in-progress, wait for it to finish before closing the connection
|
||||
this.closed = true;
|
||||
if (this.connection) {
|
||||
this.connection.dispose();
|
||||
this.connection = undefined;
|
||||
try {
|
||||
if (this.timingDump && this.timing) {
|
||||
const local = this.timing.getInfo();
|
||||
let server: ServerTimingInfo | undefined;
|
||||
let serverTimingError: string | undefined;
|
||||
const connection = this.connection;
|
||||
// Closing alone does not reject pending JSON-RPC requests.
|
||||
const onClose = connection?.onClose(() => connection.dispose());
|
||||
try {
|
||||
if (this.connected) server = await this.fetchServerTiming();
|
||||
}
|
||||
catch (error) {
|
||||
serverTimingError = String(error);
|
||||
}
|
||||
finally {
|
||||
onClose?.dispose();
|
||||
}
|
||||
this.timingDump.write(local, server, serverTimingError);
|
||||
}
|
||||
}
|
||||
if (this.socket) {
|
||||
this.socket.destroy();
|
||||
this.socket = undefined;
|
||||
finally {
|
||||
if (this.connection) {
|
||||
this.connection.dispose();
|
||||
this.connection = undefined;
|
||||
}
|
||||
if (this.socket) {
|
||||
this.socket.destroy();
|
||||
this.socket = undefined;
|
||||
}
|
||||
if (this.process) {
|
||||
// Close stdin to unblock the server's read loop, allowing it to exit cleanly.
|
||||
// The server is blocked on stdin.Read(), so just sending SIGTERM would deadlock:
|
||||
// - Node won't exit while child is alive
|
||||
// - Child can't process SIGTERM while blocked on read
|
||||
// - Read won't error until stdin is closed
|
||||
this.process.stdin?.end();
|
||||
this.process = undefined;
|
||||
}
|
||||
this.connected = false;
|
||||
}
|
||||
if (this.process) {
|
||||
// Close stdin to unblock the server's read loop, allowing it to exit cleanly.
|
||||
// The server is blocked on stdin.Read(), so just sending SIGTERM would deadlock:
|
||||
// - Node won't exit while child is alive
|
||||
// - Child can't process SIGTERM while blocked on read
|
||||
// - Read won't error until stdin is closed
|
||||
this.process.stdin?.end();
|
||||
this.process = undefined;
|
||||
}
|
||||
this.connected = false;
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,9 @@ export interface ClientSpawnOptions {
|
||||
* measures its own per-request processing time; both are combined (along
|
||||
* with an estimated transport overhead) in the snapshot returned by
|
||||
* {@link API.getTimingInfo}.
|
||||
* Setting `TS_API_TIMING_DIR` to a nonempty output directory also enables
|
||||
* collection, even when this option is false, and writes a JSON snapshot
|
||||
* when the API is closed.
|
||||
*/
|
||||
collectTiming?: boolean | undefined;
|
||||
}
|
||||
|
||||
@@ -1343,8 +1343,8 @@ export class API<FromLSP extends boolean = false> implements FormatDiagnosticsHo
|
||||
*
|
||||
* Fetching the snapshot issues a lightweight request to the server to
|
||||
* retrieve its timing collection. Collection must be enabled via the
|
||||
* `collectTiming` option; when it is not, the returned snapshot has
|
||||
* `enabled: false` and zeroed totals.
|
||||
* `collectTiming` option or `TS_API_TIMING_DIR` environment variable; when
|
||||
* it is not, the returned snapshot has `enabled: false` and zeroed totals.
|
||||
*/
|
||||
get getTimingInfo(): {
|
||||
(): TimingInfo;
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
TimingCollector,
|
||||
type TimingInfo,
|
||||
} from "../timing.ts";
|
||||
import { TimingDump } from "../timingDump.ts";
|
||||
|
||||
export type { ClientOptions, ClientSocketOptions, ClientSpawnOptions };
|
||||
|
||||
@@ -32,6 +33,8 @@ export class Client {
|
||||
private channel: SyncRpcChannel;
|
||||
private encoder = new TextEncoder();
|
||||
private timing: TimingCollector | undefined;
|
||||
private timingDump: TimingDump | undefined;
|
||||
private closed = false;
|
||||
private maxResponseBytesPerPage: number | undefined;
|
||||
|
||||
constructor(options: ClientOptions) {
|
||||
@@ -39,6 +42,10 @@ export class Client {
|
||||
throw new Error("Socket connections are not yet supported in the sync client");
|
||||
}
|
||||
|
||||
this.timingDump = TimingDump.fromEnvironment("sync", "spawn");
|
||||
if (this.timingDump) {
|
||||
options = { ...options, collectTiming: true };
|
||||
}
|
||||
const args = getAPIProcessArgs(options, false);
|
||||
this.maxResponseBytesPerPage = options.maxResponseBytesPerPage;
|
||||
|
||||
@@ -184,6 +191,24 @@ export class Client {
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.channel.close();
|
||||
if (this.closed) return;
|
||||
this.closed = true;
|
||||
try {
|
||||
if (this.timingDump && this.timing) {
|
||||
const local = this.timing.getInfo();
|
||||
let server: ServerTimingInfo | undefined;
|
||||
let serverTimingError: string | undefined;
|
||||
try {
|
||||
server = JSON.parse(this.channel.requestSync("getServerTiming", "")) as ServerTimingInfo;
|
||||
}
|
||||
catch (error) {
|
||||
serverTimingError = String(error);
|
||||
}
|
||||
this.timingDump.write(local, server, serverTimingError);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
this.channel.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,6 +113,7 @@ export class SyncRpcChannel {
|
||||
private writeFd: number;
|
||||
private pipeFd: number | undefined;
|
||||
private callbacks = new Map<string, (name: string, payload: string) => string>();
|
||||
private callbackFailure: { error: unknown; } | undefined;
|
||||
|
||||
private methodBufCache = new Map<string, Buffer>();
|
||||
|
||||
@@ -280,6 +281,9 @@ export class SyncRpcChannel {
|
||||
if (this.readFd < 0) {
|
||||
throw new Error("SyncRpcChannel is closed");
|
||||
}
|
||||
if (this.callbackFailure) {
|
||||
throw this.callbackFailure.error;
|
||||
}
|
||||
}
|
||||
|
||||
private getMethodBuf(method: string): Buffer {
|
||||
@@ -326,7 +330,14 @@ export class SyncRpcChannel {
|
||||
);
|
||||
}
|
||||
case MSG_CALL: {
|
||||
this.handleCall(this._msgName.toString("utf-8"), this._msgPayload);
|
||||
try {
|
||||
this.handleCall(this._msgName.toString("utf-8"), this._msgPayload);
|
||||
}
|
||||
catch (error) {
|
||||
// The pending response is unread, so further I/O cannot be synchronized.
|
||||
this.callbackFailure = { error };
|
||||
throw error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -182,7 +182,7 @@ export function disabledServerTimingInfo(): ServerTimingInfo {
|
||||
* requests used to fetch timing) do not misalign the two ring buffers.
|
||||
*/
|
||||
export function combineTimingInfo(client: TimingInfo, server: ServerTimingInfo): TimingInfo {
|
||||
if (!client.enabled) {
|
||||
if (!client.enabled || !server.enabled) {
|
||||
return client;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import {
|
||||
mkdirSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import {
|
||||
join,
|
||||
resolve,
|
||||
} from "node:path";
|
||||
import {
|
||||
combineTimingInfo,
|
||||
type ServerTimingInfo,
|
||||
type TimingInfo,
|
||||
} from "./timing.ts";
|
||||
|
||||
/** One final snapshot per client, written before its connection is closed. */
|
||||
export class TimingDump {
|
||||
private readonly instanceId = randomUUID();
|
||||
private readonly startedAt = new Date().toISOString();
|
||||
private readonly directory: string;
|
||||
private readonly mode: "sync" | "async";
|
||||
private readonly transport: "spawn" | "socket";
|
||||
|
||||
static fromEnvironment(mode: "sync" | "async", transport: "spawn" | "socket"): TimingDump | undefined {
|
||||
const directory = process.env.TS_API_TIMING_DIR;
|
||||
return directory ? new TimingDump(resolve(directory), mode, transport) : undefined;
|
||||
}
|
||||
|
||||
private constructor(directory: string, mode: "sync" | "async", transport: "spawn" | "socket") {
|
||||
this.directory = directory;
|
||||
this.mode = mode;
|
||||
this.transport = transport;
|
||||
}
|
||||
|
||||
write(client: TimingInfo, server: ServerTimingInfo | undefined, serverTimingError?: string): void {
|
||||
const snapshot = {
|
||||
schemaVersion: 1,
|
||||
instanceId: this.instanceId,
|
||||
pid: process.pid,
|
||||
mode: this.mode,
|
||||
transport: this.transport,
|
||||
startedAt: this.startedAt,
|
||||
closedAt: new Date().toISOString(),
|
||||
timing: server ? combineTimingInfo(client, server) : client,
|
||||
serverTiming: server ?? null,
|
||||
serverTimingError,
|
||||
};
|
||||
mkdirSync(this.directory, { recursive: true });
|
||||
writeFileSync(
|
||||
join(this.directory, `timing-${process.pid}-${this.instanceId}.json`),
|
||||
JSON.stringify(snapshot) + "\n",
|
||||
{ flag: "wx" },
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
import {
|
||||
createMessageConnection,
|
||||
SocketMessageReader,
|
||||
SocketMessageWriter,
|
||||
} from "#vscode-jsonrpc/node";
|
||||
import { API as AsyncAPI } from "@typescript/typescript/async";
|
||||
import { API as SyncAPI } from "@typescript/typescript/sync";
|
||||
import assert from "node:assert/strict";
|
||||
import { once } from "node:events";
|
||||
import {
|
||||
mkdtempSync,
|
||||
readdirSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
} from "node:fs";
|
||||
import { createServer } from "node:net";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { test } from "node:test";
|
||||
import {
|
||||
combineTimingInfo,
|
||||
disabledServerTimingInfo,
|
||||
TimingCollector,
|
||||
} from "../src/api/timing.ts";
|
||||
import { createVirtualFileSystem } from "./testUtils.ts";
|
||||
|
||||
test("disabled server timing preserves the client-only snapshot", () => {
|
||||
const collector = new TimingCollector();
|
||||
collector.record({ method: "initialize", roundTripMs: 10, bytesSent: 1, bytesReceived: 1 });
|
||||
const local = collector.getInfo();
|
||||
assert.strictEqual(combineTimingInfo(local, disabledServerTimingInfo()), local);
|
||||
});
|
||||
|
||||
test("timing dumps", async t => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "ts-timing-"));
|
||||
const original = process.env.TS_API_TIMING_DIR;
|
||||
t.after(() => {
|
||||
if (original === undefined) delete process.env.TS_API_TIMING_DIR;
|
||||
else process.env.TS_API_TIMING_DIR = original;
|
||||
rmSync(directory, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
function assertDumpCount(count: number): void {
|
||||
const files = readdirSync(directory).filter(file => file.endsWith(".json"));
|
||||
assert.equal(files.length, count);
|
||||
for (const file of files) {
|
||||
assert.ok(Object.keys(JSON.parse(readFileSync(join(directory, file), "utf8"))).length > 0);
|
||||
}
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
for (const [mode, API] of [["async", AsyncAPI], ["sync", SyncAPI]] as const) {
|
||||
for (const value of [undefined, "", directory]) {
|
||||
await t.test(`${mode}: dumping ${value ? "enabled" : value === "" ? "empty" : "unset"}`, async () => {
|
||||
if (value === undefined) delete process.env.TS_API_TIMING_DIR;
|
||||
else process.env.TS_API_TIMING_DIR = value;
|
||||
const api = new API({ collectTiming: false });
|
||||
try {
|
||||
await api.parseCommandLine([]);
|
||||
assert.equal((await api.getTimingInfo()).enabled, !!value);
|
||||
assertDumpCount(count);
|
||||
}
|
||||
finally {
|
||||
await api.close();
|
||||
}
|
||||
if (value) count++;
|
||||
assertDumpCount(count);
|
||||
await api.close();
|
||||
assertDumpCount(count);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
process.env.TS_API_TIMING_DIR = directory;
|
||||
await t.test("sync: preserves a dump after a filesystem callback throws", async t => {
|
||||
const warning = t.mock.method(process, "emitWarning", () => {});
|
||||
const api = new SyncAPI({
|
||||
fs: {
|
||||
...createVirtualFileSystem({}),
|
||||
readFile() {
|
||||
throw new Error("read failed");
|
||||
},
|
||||
},
|
||||
});
|
||||
try {
|
||||
api.parseCommandLine([]);
|
||||
assert.throws(() => api.readConfigFile("/tsconfig.json"), /read failed/);
|
||||
assert.throws(() => api.parseCommandLine([]), /read failed/);
|
||||
assert.throws(() => api.getTimingInfo(), /read failed/);
|
||||
}
|
||||
finally {
|
||||
api.close();
|
||||
}
|
||||
assertDumpCount(++count);
|
||||
assert.equal(warning.mock.callCount(), 0);
|
||||
});
|
||||
|
||||
for (const scenario of ["error", "disconnect", "disabled"] as const) {
|
||||
await t.test(`async: preserves a dump when server timing is ${scenario}`, { timeout: 5000 }, async t => {
|
||||
const warning = t.mock.method(process, "emitWarning", () => {});
|
||||
const pipe = process.platform === "win32" ? `\\\\.\\pipe\\ts-timing-${process.pid}` : join(directory, "api.sock");
|
||||
let disconnect = () => {};
|
||||
const server = createServer(socket => {
|
||||
const connection = createMessageConnection(new SocketMessageReader(socket), new SocketMessageWriter(socket));
|
||||
disconnect = () => {
|
||||
connection.dispose();
|
||||
socket.destroy();
|
||||
};
|
||||
connection.onRequest("initialize", () => ({ currentDirectory: process.cwd(), caseSensitivity: 1 }));
|
||||
connection.onRequest("getServerTiming", () => {
|
||||
if (scenario === "disconnect") {
|
||||
disconnect();
|
||||
return new Promise(() => {});
|
||||
}
|
||||
if (scenario === "disabled") return disabledServerTimingInfo();
|
||||
throw new Error("server timing unavailable");
|
||||
});
|
||||
connection.listen();
|
||||
});
|
||||
t.after(() => {
|
||||
disconnect();
|
||||
return new Promise<void>(resolve => server.close(() => resolve()));
|
||||
});
|
||||
server.listen(pipe);
|
||||
await once(server, "listening");
|
||||
const api = await AsyncAPI.fromLSPConnection({ pipe });
|
||||
await api.close();
|
||||
assertDumpCount(++count);
|
||||
assert.equal(warning.mock.callCount(), 0);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -37,7 +37,7 @@ extends:
|
||||
fetchDepth: 1
|
||||
fetchTags: false
|
||||
retryCount: 3
|
||||
sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
|
||||
sourceAnalysisPool: VSEng-MicroBuildVSStable
|
||||
featureFlags:
|
||||
golang:
|
||||
internalModuleProxy:
|
||||
|
||||
Executable → Regular
+1
-1
@@ -43,7 +43,7 @@ extends:
|
||||
|
||||
parameters:
|
||||
sdl:
|
||||
sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
|
||||
sourceAnalysisPool: VSEng-MicroBuildVSStable
|
||||
pool:
|
||||
name: AzurePipelines-EO
|
||||
image: 1ESPT-Ubuntu22.04
|
||||
|
||||
@@ -31,7 +31,7 @@ extends:
|
||||
fetchDepth: 0
|
||||
fetchTags: false
|
||||
retryCount: 3
|
||||
sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
|
||||
sourceAnalysisPool: VSEng-MicroBuildVSStable
|
||||
pool:
|
||||
name: AzurePipelines-EO
|
||||
image: 1ESPT-Ubuntu22.04
|
||||
|
||||
@@ -38,7 +38,7 @@ extends:
|
||||
|
||||
parameters:
|
||||
sdl:
|
||||
sourceAnalysisPool: VSEngSS-MicroBuild2022-1ES
|
||||
sourceAnalysisPool: VSEng-MicroBuildVSStable
|
||||
pool:
|
||||
name: AzurePipelines-EO
|
||||
image: 1ESPT-Ubuntu22.04
|
||||
|
||||
@@ -316,3 +316,49 @@ func TestCreateProgramReportsNonCompositeProjectReference(t *testing.T) {
|
||||
}
|
||||
assert.DeepEqual(t, codes, []int32{6306})
|
||||
}
|
||||
|
||||
func TestCreateSnapshotResolvesPathsRelativeToParsedConfigDirectory(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const (
|
||||
mainFile = "/project/main.ts"
|
||||
libFile = "/project/types/lib.d.ts"
|
||||
)
|
||||
init, _ := projecttestutil.GetSessionInitOptions(map[string]any{
|
||||
mainFile: `import { x } from "lib"; export const y: number = x;`,
|
||||
libFile: `export declare const x: number;`,
|
||||
}, nil, &projecttestutil.TypingsInstallerOptions{})
|
||||
init.Options.CurrentDirectory = "/somewhere-else"
|
||||
session := NewStandaloneSession(init, nil)
|
||||
defer session.Close()
|
||||
|
||||
var parseParams ParseJsonConfigFileContentParams
|
||||
assert.NilError(t, json.Unmarshal([]byte(`{
|
||||
"json": {
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"noLib": true,
|
||||
"types": [],
|
||||
"paths": { "lib": ["./types/lib.d.ts"] }
|
||||
}
|
||||
},
|
||||
"configDirectory": "/project"
|
||||
}`), &parseParams))
|
||||
parsed, err := session.handleParseJsonConfigFileContent(context.Background(), &parseParams)
|
||||
assert.NilError(t, err)
|
||||
|
||||
// Round-trip the parsed options through JSON as an API client would.
|
||||
encodedOptions, err := json.Marshal(parsed.Options)
|
||||
assert.NilError(t, err)
|
||||
var createParams CreateSnapshotParams
|
||||
assert.NilError(t, json.Unmarshal([]byte(`{"createPrograms":[{"rootFiles":["`+mainFile+`"],"compilerOptions":`+string(encodedOptions)+`}]}`), &createParams))
|
||||
|
||||
response, err := session.handleCreateSnapshot(context.Background(), &createParams)
|
||||
assert.NilError(t, err)
|
||||
snapshot, err := session.getSnapshotData(response.Snapshot)
|
||||
assert.NilError(t, err)
|
||||
program, err := snapshot.getProgram(response.Projects[0].Id)
|
||||
assert.NilError(t, err)
|
||||
assert.Assert(t, program.GetSourceFile(libFile) != nil, "expected 'lib' to resolve via paths relative to /project")
|
||||
}
|
||||
@@ -639,7 +639,7 @@ type Checker struct {
|
||||
subtypeReductionCache map[CacheHashKey][]*Type
|
||||
cachedTypes map[CachedTypeKey]*Type
|
||||
cachedSignatures map[CachedSignatureKey]*Signature
|
||||
undefinedProperties map[string]*ast.Symbol
|
||||
undefinedProperties map[*ast.Symbol]*ast.Symbol
|
||||
narrowedTypes map[NarrowedTypeKey]*Type
|
||||
assignmentReducedTypes map[AssignmentReducedKey]*Type
|
||||
discriminatedContextualTypes map[DiscriminatedContextualTypeKey]*Type
|
||||
@@ -977,7 +977,7 @@ func NewChecker(program Program, tracer *Tracer) (*Checker, *sync.Mutex) {
|
||||
c.subtypeReductionCache = make(map[CacheHashKey][]*Type)
|
||||
c.cachedTypes = make(map[CachedTypeKey]*Type)
|
||||
c.cachedSignatures = make(map[CachedSignatureKey]*Signature)
|
||||
c.undefinedProperties = make(map[string]*ast.Symbol)
|
||||
c.undefinedProperties = make(map[*ast.Symbol]*ast.Symbol)
|
||||
c.narrowedTypes = make(map[NarrowedTypeKey]*Type)
|
||||
c.assignmentReducedTypes = make(map[AssignmentReducedKey]*Type)
|
||||
c.discriminatedContextualTypes = make(map[DiscriminatedContextualTypeKey]*Type)
|
||||
@@ -18927,12 +18927,12 @@ func (c *Checker) getSiblingsOfContext(context *WideningContext) []*Type {
|
||||
}
|
||||
|
||||
func (c *Checker) getUndefinedProperty(prop *ast.Symbol) *ast.Symbol {
|
||||
if cached := c.undefinedProperties[prop.Name()]; cached != nil {
|
||||
if cached := c.undefinedProperties[prop]; cached != nil {
|
||||
return cached
|
||||
}
|
||||
result := c.createSymbolWithType(prop, c.undefinedOrMissingType)
|
||||
result.SetFlags(result.Flags() | ast.SymbolFlagsOptional)
|
||||
c.undefinedProperties[prop.Name()] = result
|
||||
c.undefinedProperties[prop] = result
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
package incremental
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"maps"
|
||||
"slices"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/microsoft/TypeScript/tsc/internal/collections"
|
||||
"github.com/microsoft/TypeScript/tsc/internal/compiler"
|
||||
"github.com/microsoft/TypeScript/tsc/internal/core"
|
||||
"github.com/microsoft/TypeScript/tsc/internal/json"
|
||||
"github.com/microsoft/TypeScript/tsc/internal/tsoptions"
|
||||
"github.com/microsoft/TypeScript/tsc/internal/tspath"
|
||||
"github.com/microsoft/TypeScript/tsc/internal/vfs/vfstest"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
@@ -34,3 +44,405 @@ func TestBuildInfoPathJSONRoundTrip(t *testing.T) {
|
||||
assert.DeepEqual(t, roundTripped.FileNames, buildInfo.FileNames)
|
||||
assert.Equal(t, roundTripped.LatestChangedDtsFile, buildInfo.LatestChangedDtsFile)
|
||||
}
|
||||
|
||||
const deletionTestLib = `interface Array<T> {}
|
||||
interface Boolean {}
|
||||
interface CallableFunction {}
|
||||
interface Function {}
|
||||
interface IArguments {}
|
||||
interface NewableFunction {}
|
||||
interface Number {}
|
||||
interface Object {}
|
||||
interface RegExp {}
|
||||
interface String {}
|
||||
`
|
||||
|
||||
func newDeletionTestProgram(files map[string]string, roots []string, options *core.CompilerOptions, old *Program) *Program {
|
||||
files = maps.Clone(files)
|
||||
files["/lib/"+tsoptions.GetDefaultLibFileName(options)] = files["/lib/lib.d.ts"]
|
||||
host := compiler.NewCompilerHost(vfstest.FromMap(files, tspath.CaseSensitive), "/lib", nil, nil, nil)
|
||||
paths := core.Map(roots, func(name string) tspath.RootedFilePath {
|
||||
return tspath.ToRootedFilePath(name, "/project")
|
||||
})
|
||||
config := tsoptions.NewParsedCommandLine(options, paths, nil, "/project", tspath.CaseSensitive)
|
||||
program := compiler.NewProgram(compiler.ProgramOptions{Config: config, Host: host})
|
||||
return NewProgram(program, old, CreateHost(host), nil, false)
|
||||
}
|
||||
|
||||
func TestDeletedGlobalInvalidatesAllSourceFiles(t *testing.T) {
|
||||
t.Parallel()
|
||||
current := newDeletionTestProgram(map[string]string{
|
||||
"/lib/lib.d.ts": deletionTestLib,
|
||||
"/project/consumer.ts": "export const unchanged = 1;",
|
||||
}, []string{"consumer.ts"}, &core.CompilerOptions{Incremental: core.TSTrue, NoEmit: core.TSTrue}, nil)
|
||||
old := &Program{snapshot: &snapshot{}}
|
||||
current.snapshot.fileInfos.Range(func(path tspath.PathKey, info *FileInfo) bool {
|
||||
old.snapshot.fileInfos.Store(path, info)
|
||||
return true
|
||||
})
|
||||
for _, path := range []tspath.PathKey{"/project/first.d.ts", "/project/second.d.ts"} {
|
||||
old.snapshot.fileInfos.Store(path, &FileInfo{})
|
||||
}
|
||||
deletedOrder := func() []tspath.PathKey {
|
||||
var paths []tspath.PathKey
|
||||
old.snapshot.fileInfos.Range(func(path tspath.PathKey, _ *FileInfo) bool {
|
||||
if _, retained := current.snapshot.fileInfos.Load(path); !retained {
|
||||
paths = append(paths, path)
|
||||
}
|
||||
return true
|
||||
})
|
||||
return paths
|
||||
}
|
||||
order := deletedOrder()
|
||||
if !slices.Equal(order, deletedOrder()) {
|
||||
t.Fatal("file iteration changed without writes")
|
||||
}
|
||||
info, _ := old.snapshot.fileInfos.Load(order[len(order)-1])
|
||||
info.affectsGlobalScope = true
|
||||
to := &toProgramSnapshot{program: current.program, snapshot: current.snapshot, oldProgram: old}
|
||||
to.handleFileDelete()
|
||||
if !to.globalFileRemoved || !current.snapshot.changedFilesSet.Has("/project/consumer.ts") {
|
||||
t.Fatalf("global deletion after non-global deletion did not invalidate consumer: global=%t changed=%t",
|
||||
to.globalFileRemoved, current.snapshot.changedFilesSet.Has("/project/consumer.ts"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestGlobalDeletionInvalidatesRetainedLibraryDiagnostics(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, single := range []core.Tristate{core.TSFalse, core.TSTrue} {
|
||||
for _, kind := range []string{"new error", "cleared error", "scope loss"} {
|
||||
t.Run(fmt.Sprintf("%v/%s", single, kind), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := &core.CompilerOptions{
|
||||
Incremental: core.TSTrue, NoEmit: core.TSTrue,
|
||||
SingleThreaded: single, TsBuildInfoFile: "/project/state.tsbuildinfo",
|
||||
}
|
||||
library := deletionTestLib + "interface LibraryConsumer { property: RemovedGlobal; }"
|
||||
global := "interface RemovedGlobal { x: string; }"
|
||||
if kind == "cleared error" {
|
||||
library = deletionTestLib + "interface Shared<T> {}"
|
||||
global = "interface Shared<T, U> {}"
|
||||
}
|
||||
files := map[string]string{
|
||||
"/lib/lib.d.ts": library,
|
||||
"/project/global.d.ts": global,
|
||||
"/project/consumer.ts": "export const unchanged = 1;",
|
||||
"/project/module.d.ts": "export interface Unrelated {}",
|
||||
}
|
||||
old := newDeletionTestProgram(files, []string{"global.d.ts", "consumer.ts", "module.d.ts"}, options, nil)
|
||||
old.GetSemanticDiagnostics(t.Context(), nil)
|
||||
old.Emit(t.Context(), compiler.EmitOptions{})
|
||||
roots := []string{"consumer.ts"}
|
||||
if kind == "scope loss" {
|
||||
files["/project/global.d.ts"] = "export " + global
|
||||
roots = append(roots, "global.d.ts")
|
||||
} else {
|
||||
delete(files, "/project/global.d.ts")
|
||||
}
|
||||
delete(files, "/project/module.d.ts")
|
||||
current := newDeletionTestProgram(files, roots, options, old)
|
||||
cold := newDeletionTestProgram(files, roots, options, nil)
|
||||
actual := current.GetSemanticDiagnostics(t.Context(), nil)
|
||||
expected := cold.GetSemanticDiagnostics(t.Context(), nil)
|
||||
if kind == "cleared error" {
|
||||
if len(expected) != 0 {
|
||||
t.Fatalf("cold build should have no errors: %v", expected)
|
||||
}
|
||||
} else if len(expected) != 1 || expected[0].Code() != 2304 {
|
||||
t.Fatalf("cold build should report one TS2304: %v", expected)
|
||||
}
|
||||
if len(actual) != len(expected) {
|
||||
t.Fatalf("incremental diagnostics=%d, cold=%d", len(actual), len(expected))
|
||||
}
|
||||
if len(actual) != 0 && actual[0].Code() != expected[0].Code() {
|
||||
t.Fatalf("incremental diagnostic=%d, cold=%d", actual[0].Code(), expected[0].Code())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEmptyProgramDeletionEmitsBuildInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
for flags := range 8 {
|
||||
for _, roots := range [][]string{{"global.d.ts"}, {"module.d.ts"}, {"global.d.ts", "module.d.ts"}} {
|
||||
t.Run(fmt.Sprintf("%d/%v", flags, roots), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := &core.CompilerOptions{
|
||||
Incremental: core.TSTrue, TsBuildInfoFile: "/project/state.tsbuildinfo",
|
||||
NoCheck: core.IfElse(flags&1 != 0, core.TSTrue, core.TSFalse),
|
||||
NoEmit: core.IfElse(flags&2 != 0, core.TSTrue, core.TSFalse),
|
||||
Composite: core.IfElse(flags&4 != 0, core.TSTrue, core.TSFalse),
|
||||
}
|
||||
files := map[string]string{
|
||||
"/lib/lib.d.ts": deletionTestLib,
|
||||
"/project/global.d.ts": "interface RemovedGlobal {}",
|
||||
"/project/module.d.ts": "export interface Unrelated {}",
|
||||
}
|
||||
old := newDeletionTestProgram(files, roots, options, nil)
|
||||
old.GetSemanticDiagnostics(t.Context(), nil)
|
||||
old.Emit(t.Context(), compiler.EmitOptions{})
|
||||
if old.snapshot.buildInfoEmitPending.Load() {
|
||||
t.Fatal("initial build info was not emitted")
|
||||
}
|
||||
delete(files, "/project/global.d.ts")
|
||||
delete(files, "/project/module.d.ts")
|
||||
current := newDeletionTestProgram(files, nil, options, old)
|
||||
if len(current.GetSourceFiles()) != 0 {
|
||||
t.Fatal("new program is not empty")
|
||||
}
|
||||
writes := 0
|
||||
current.Emit(t.Context(), compiler.EmitOptions{
|
||||
WriteFile: func(name tspath.RootedFilePath, text string, _ *compiler.WriteFileData) error {
|
||||
if name.ExtensionIs(tspath.ExtensionTsBuildInfo) {
|
||||
writes++
|
||||
var info struct {
|
||||
FileNames []string `json:"fileNames"`
|
||||
FileInfos []json.Value `json:"fileInfos"`
|
||||
ChangeFileSet []int `json:"changeFileSet"`
|
||||
AffectedFilesPendingEmit []json.Value `json:"affectedFilesPendingEmit"`
|
||||
}
|
||||
if err := json.Unmarshal([]byte(text), &info); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(info.FileNames) != 0 || len(info.FileInfos) != 0 || len(info.ChangeFileSet) != 0 || len(info.AffectedFilesPendingEmit) != 0 {
|
||||
t.Fatalf("empty program persisted removed state: %+v", info)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
})
|
||||
if writes != 1 {
|
||||
t.Fatalf("build-info writes after deleting every source = %d, want 1", writes)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUncheckedDeletedFilesDiscardPendingState(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := &core.CompilerOptions{
|
||||
Incremental: core.TSTrue, NoEmit: core.TSTrue, NoCheck: core.TSTrue,
|
||||
TsBuildInfoFile: "/project/state.tsbuildinfo",
|
||||
}
|
||||
files := map[string]string{
|
||||
"/lib/lib.d.ts": deletionTestLib,
|
||||
"/project/stable.ts": "export const stable = 1;",
|
||||
}
|
||||
old := newDeletionTestProgram(files, []string{"stable.ts"}, options, nil)
|
||||
old.Emit(t.Context(), compiler.EmitOptions{})
|
||||
files["/project/first.ts"] = "export const first = 1;"
|
||||
files["/project/second.ts"] = "export const second = 1;"
|
||||
added := newDeletionTestProgram(files, []string{"stable.ts", "first.ts", "second.ts"}, options, old)
|
||||
added.Emit(t.Context(), compiler.EmitOptions{})
|
||||
for _, path := range []tspath.PathKey{"/project/first.ts", "/project/second.ts"} {
|
||||
if !added.snapshot.changedFilesSet.Has(path) {
|
||||
t.Fatalf("new unchecked file %s not pending", path)
|
||||
}
|
||||
added.snapshot.affectedFilesPendingEmit.Store(path, FileEmitKindJs)
|
||||
}
|
||||
delete(files, "/project/first.ts")
|
||||
delete(files, "/project/second.ts")
|
||||
current := newDeletionTestProgram(files, []string{"stable.ts"}, options, added)
|
||||
for _, path := range []tspath.PathKey{"/project/first.ts", "/project/second.ts"} {
|
||||
if current.snapshot.changedFilesSet.Has(path) {
|
||||
t.Errorf("removed unchecked file %s still in change set", path)
|
||||
}
|
||||
if _, pending := current.snapshot.affectedFilesPendingEmit.Load(path); pending {
|
||||
t.Errorf("removed file %s still pending emit", path)
|
||||
}
|
||||
}
|
||||
info, err := snapshotToBuildInfo(current.snapshot, current.program, options.TsBuildInfoFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(info.FileNames) != len(info.FileInfos) || len(info.ChangeFileSet) != 0 {
|
||||
t.Fatalf("invalid build-info file state: names=%d infos=%d changes=%v", len(info.FileNames), len(info.FileInfos), info.ChangeFileSet)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModuleDeletionPreservesUnrelatedCachedDiagnostics(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, skip := range []core.Tristate{core.TSFalse, core.TSTrue} {
|
||||
t.Run(fmt.Sprint(skip), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := &core.CompilerOptions{
|
||||
Incremental: core.TSTrue, NoEmit: core.TSTrue, SkipDefaultLibCheck: skip,
|
||||
TsBuildInfoFile: "/project/state.tsbuildinfo",
|
||||
}
|
||||
files := map[string]string{
|
||||
"/lib/lib.d.ts": deletionTestLib,
|
||||
"/project/consumer.ts": "export const unchanged = 1;",
|
||||
"/project/module.d.ts": "export interface Unrelated {}",
|
||||
}
|
||||
old := newDeletionTestProgram(files, []string{"consumer.ts", "module.d.ts"}, options, nil)
|
||||
old.GetSemanticDiagnostics(t.Context(), nil)
|
||||
old.Emit(t.Context(), compiler.EmitOptions{})
|
||||
delete(files, "/project/module.d.ts")
|
||||
current := newDeletionTestProgram(files, []string{"consumer.ts"}, options, old)
|
||||
if current.snapshot.changedFilesSet.Has("/project/consumer.ts") {
|
||||
t.Fatal("unrelated module deletion invalidated consumer")
|
||||
}
|
||||
for _, file := range current.GetSourceFiles() {
|
||||
previous, ok := old.snapshot.semanticDiagnosticsPerFile.Load(file.PathKey())
|
||||
if !ok {
|
||||
t.Fatalf("initial diagnostics for %s were not cached", file.FileName())
|
||||
}
|
||||
cached, ok := current.snapshot.semanticDiagnosticsPerFile.Load(file.PathKey())
|
||||
if !ok || cached != previous {
|
||||
t.Fatalf("unrelated cached diagnostics for %s not reused", file.FileName())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeletedFilesCleanupAfterGlobalDeletion(t *testing.T) {
|
||||
t.Parallel()
|
||||
current := newDeletionTestProgram(map[string]string{"/lib/lib.d.ts": deletionTestLib}, nil,
|
||||
&core.CompilerOptions{Incremental: core.TSTrue}, nil)
|
||||
old := &Program{snapshot: &snapshot{}}
|
||||
deleted := []tspath.PathKey{"/project/first.d.ts", "/project/second.d.ts", "/project/third.d.ts"}
|
||||
for _, path := range deleted {
|
||||
old.snapshot.fileInfos.Store(path, &FileInfo{affectsGlobalScope: true})
|
||||
current.snapshot.changedFilesSet.Add(path)
|
||||
current.snapshot.affectedFilesPendingEmit.Store(path, FileEmitKindJs)
|
||||
}
|
||||
to := &toProgramSnapshot{program: current.program, snapshot: current.snapshot, oldProgram: old}
|
||||
to.handleFileDelete()
|
||||
for _, path := range deleted {
|
||||
if current.snapshot.changedFilesSet.Has(path) {
|
||||
t.Errorf("removed path %s still in change set", path)
|
||||
}
|
||||
if _, pending := current.snapshot.affectedFilesPendingEmit.Load(path); pending {
|
||||
t.Errorf("removed path %s still pending emit", path)
|
||||
}
|
||||
}
|
||||
if !current.snapshot.buildInfoEmitPending.Load() {
|
||||
t.Error("global deletion did not mark build info pending")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemovedPendingPathsWithoutFileInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := &core.CompilerOptions{
|
||||
Incremental: core.TSTrue, NoCheck: core.TSTrue, NoEmit: core.TSTrue,
|
||||
TsBuildInfoFile: "/project/state.tsbuildinfo",
|
||||
}
|
||||
files := map[string]string{
|
||||
"/lib/lib.d.ts": deletionTestLib,
|
||||
"/project/stable.ts": "export const stable = 1;",
|
||||
}
|
||||
old := newDeletionTestProgram(files, []string{"stable.ts"}, options, nil)
|
||||
old.Emit(t.Context(), compiler.EmitOptions{})
|
||||
old.snapshot.changedFilesSet.Add("/project/missing.ts")
|
||||
old.snapshot.affectedFilesPendingEmit.Store("/project/missing.ts", FileEmitKindJs)
|
||||
current := newDeletionTestProgram(files, []string{"stable.ts"}, options, old)
|
||||
if current.snapshot.changedFilesSet.Has("/project/missing.ts") {
|
||||
t.Error("removed pending path without file info was retained")
|
||||
}
|
||||
if _, pending := current.snapshot.affectedFilesPendingEmit.Load("/project/missing.ts"); pending {
|
||||
t.Error("removed pending emit path without file info was retained")
|
||||
}
|
||||
if !current.snapshot.buildInfoEmitPending.Load() {
|
||||
t.Error("discarding obsolete pending state did not mark build info pending")
|
||||
}
|
||||
info, err := snapshotToBuildInfo(current.snapshot, current.program, options.TsBuildInfoFile)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(info.FileNames) != len(info.FileInfos) {
|
||||
t.Fatalf("invalid cached file state: names=%d infos=%d", len(info.FileNames), len(info.FileInfos))
|
||||
}
|
||||
}
|
||||
|
||||
func TestForEachDeletedFileVisitsEveryRemovedPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
order := []tspath.PathKey{"/first.ts", "/second.ts", "/third.ts", "/fourth.ts"}
|
||||
var visitOrders func(int)
|
||||
visitOrders = func(index int) {
|
||||
if index != len(order) {
|
||||
for next := index; next < len(order); next++ {
|
||||
order[index], order[next] = order[next], order[index]
|
||||
visitOrders(index + 1)
|
||||
order[index], order[next] = order[next], order[index]
|
||||
}
|
||||
return
|
||||
}
|
||||
for retained := range 16 {
|
||||
for global := range 16 {
|
||||
var current collections.SyncMap[tspath.PathKey, *FileInfo]
|
||||
infos := make(map[tspath.PathKey]*FileInfo)
|
||||
var expected []tspath.PathKey
|
||||
for i, path := range order {
|
||||
infos[path] = &FileInfo{affectsGlobalScope: global&(1<<i) != 0}
|
||||
if retained&(1<<i) != 0 {
|
||||
current.Store(path, &FileInfo{})
|
||||
} else {
|
||||
expected = append(expected, path)
|
||||
}
|
||||
}
|
||||
current.Store("/new.ts", &FileInfo{})
|
||||
var actual []tspath.PathKey
|
||||
forEachDeletedFile(func(callback func(tspath.PathKey, *FileInfo) bool) {
|
||||
for _, path := range order {
|
||||
if !callback(path, infos[path]) {
|
||||
t.Fatal("deleted-file enumeration stopped early")
|
||||
}
|
||||
}
|
||||
}, ¤t, func(path tspath.PathKey, info *FileInfo) {
|
||||
if info != infos[path] {
|
||||
t.Fatal("deleted-file callback lost old metadata")
|
||||
}
|
||||
actual = append(actual, path)
|
||||
})
|
||||
if !slices.Equal(actual, expected) {
|
||||
t.Fatalf("order=%v retained=%d global=%d: callbacks=%v, want %v", order, retained, global, actual, expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visitOrders(0)
|
||||
}
|
||||
|
||||
func TestGlobalDeletionPreservesSkippedLibraryDiagnostics(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, skipDefault := range []bool{false, true} {
|
||||
t.Run(strconv.FormatBool(skipDefault), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
options := &core.CompilerOptions{Incremental: core.TSTrue, NoEmit: core.TSTrue}
|
||||
if skipDefault {
|
||||
options.SkipDefaultLibCheck = core.TSTrue
|
||||
} else {
|
||||
options.SkipLibCheck = core.TSTrue
|
||||
}
|
||||
files := map[string]string{
|
||||
"/lib/lib.d.ts": deletionTestLib + "interface LibraryConsumer { property: RemovedGlobal; }",
|
||||
"/project/global.d.ts": "interface RemovedGlobal {}",
|
||||
"/project/consumer.ts": "export const unchanged = 1;",
|
||||
}
|
||||
old := newDeletionTestProgram(files, []string{"consumer.ts", "global.d.ts"}, options, nil)
|
||||
old.GetSemanticDiagnostics(t.Context(), nil)
|
||||
old.Emit(t.Context(), compiler.EmitOptions{})
|
||||
delete(files, "/project/global.d.ts")
|
||||
current := newDeletionTestProgram(files, []string{"consumer.ts"}, options, old)
|
||||
for _, file := range current.GetSourceFiles() {
|
||||
if !current.program.IsSourceFileDefaultLibrary(file.PathKey()) {
|
||||
continue
|
||||
}
|
||||
previous, ok := old.snapshot.semanticDiagnosticsPerFile.Load(file.PathKey())
|
||||
cached, reused := current.snapshot.semanticDiagnosticsPerFile.Load(file.PathKey())
|
||||
if !ok || !reused || cached != previous {
|
||||
t.Fatalf("skipped library diagnostics for %s not reused", file.FileName())
|
||||
}
|
||||
if current.snapshot.changedFilesSet.Has(file.PathKey()) {
|
||||
t.Fatalf("global removal marked skipped library %s changed", file.FileName())
|
||||
}
|
||||
}
|
||||
if diagnostics := current.GetSemanticDiagnostics(t.Context(), nil); len(diagnostics) != 0 {
|
||||
t.Fatalf("skipped library produced diagnostics: %v", diagnostics)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -51,16 +51,24 @@ func (t *toProgramSnapshot) reuseFromOldProgram() {
|
||||
if t.snapshot.options.Composite.IsTrue() {
|
||||
t.snapshot.latestChangedDtsFile = t.oldProgram.snapshot.latestChangedDtsFile
|
||||
}
|
||||
t.snapshot.buildInfoEmitPending.Store(t.oldProgram.snapshot.buildInfoEmitPending.Load())
|
||||
// Copy old snapshot's changed files set
|
||||
t.oldProgram.snapshot.changedFilesSet.Range(func(key tspath.PathKey) bool {
|
||||
t.snapshot.changedFilesSet.Add(key)
|
||||
if t.program.GetSourceFileByPath(key) != nil {
|
||||
t.snapshot.changedFilesSet.Add(key)
|
||||
} else {
|
||||
t.snapshot.buildInfoEmitPending.Store(true)
|
||||
}
|
||||
return true
|
||||
})
|
||||
t.oldProgram.snapshot.affectedFilesPendingEmit.Range(func(key tspath.PathKey, emitKind FileEmitKind) bool {
|
||||
t.snapshot.affectedFilesPendingEmit.Store(key, emitKind)
|
||||
if t.program.GetSourceFileByPath(key) != nil {
|
||||
t.snapshot.affectedFilesPendingEmit.Store(key, emitKind)
|
||||
} else {
|
||||
t.snapshot.buildInfoEmitPending.Store(true)
|
||||
}
|
||||
return true
|
||||
})
|
||||
t.snapshot.buildInfoEmitPending.Store(t.oldProgram.snapshot.buildInfoEmitPending.Load())
|
||||
t.snapshot.hasErrorsFromOldState = t.oldProgram.snapshot.hasErrors
|
||||
t.snapshot.hasSemanticErrorsFromOldState = t.oldProgram.snapshot.hasSemanticErrors
|
||||
t.snapshot.packageJsonsFromOldState = t.oldProgram.snapshot.packageJsons
|
||||
@@ -161,21 +169,41 @@ func (t *toProgramSnapshot) computeProgramFileChanges() {
|
||||
|
||||
func (t *toProgramSnapshot) handleFileDelete() {
|
||||
if t.oldProgram != nil {
|
||||
// If the global file is removed, add all files as changed
|
||||
t.oldProgram.snapshot.fileInfos.Range(func(filePath tspath.PathKey, oldInfo *FileInfo) bool {
|
||||
if _, ok := t.snapshot.fileInfos.Load(filePath); !ok {
|
||||
if oldInfo.affectsGlobalScope {
|
||||
for _, file := range t.snapshot.getAllFilesExcludingDefaultLibraryFile(t.program, nil) {
|
||||
t.snapshot.addFileToChangeSet(file.PathKey())
|
||||
}
|
||||
t.globalFileRemoved = true
|
||||
} else {
|
||||
t.snapshot.buildInfoEmitPending.Store(true)
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
forEachDeletedFile(t.oldProgram.snapshot.fileInfos.Range, &t.snapshot.fileInfos, t.handleDeletedFile)
|
||||
if t.globalFileRemoved {
|
||||
t.invalidateGlobalScope()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func forEachDeletedFile(
|
||||
rangeOldFileInfos func(func(tspath.PathKey, *FileInfo) bool),
|
||||
newFileInfos *collections.SyncMap[tspath.PathKey, *FileInfo],
|
||||
onDeletedFile func(tspath.PathKey, *FileInfo),
|
||||
) {
|
||||
rangeOldFileInfos(func(filePath tspath.PathKey, oldInfo *FileInfo) bool {
|
||||
if _, retained := newFileInfos.Load(filePath); !retained {
|
||||
onDeletedFile(filePath, oldInfo)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
func (t *toProgramSnapshot) handleDeletedFile(filePath tspath.PathKey, oldInfo *FileInfo) {
|
||||
t.snapshot.buildInfoEmitPending.Store(true)
|
||||
t.snapshot.changedFilesSet.Delete(filePath)
|
||||
t.snapshot.affectedFilesPendingEmit.Delete(filePath)
|
||||
t.globalFileRemoved = t.globalFileRemoved || oldInfo.affectsGlobalScope
|
||||
}
|
||||
|
||||
func (t *toProgramSnapshot) invalidateGlobalScope() {
|
||||
t.snapshot.buildInfoEmitPending.Store(true)
|
||||
for _, file := range t.program.GetSourceFiles() {
|
||||
if !t.program.IsSourceFileDefaultLibrary(file.PathKey()) {
|
||||
t.snapshot.addFileToChangeSet(file.PathKey())
|
||||
} else if !t.program.SkipTypeChecking(file, true) {
|
||||
t.snapshot.semanticDiagnosticsPerFile.Delete(file.PathKey())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,9 +223,7 @@ func (t *toProgramSnapshot) handleGlobalScopeChange() {
|
||||
return true
|
||||
})
|
||||
if globalScopeLost {
|
||||
for _, file := range t.snapshot.getAllFilesExcludingDefaultLibraryFile(t.program, nil) {
|
||||
t.snapshot.addFileToChangeSet(file.PathKey())
|
||||
}
|
||||
t.invalidateGlobalScope()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -325,6 +325,43 @@ func TestTscCommandline(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
for _, value := range []string{"false", "true", "omitted"} {
|
||||
option := ""
|
||||
if value != "omitted" {
|
||||
option = `, "alwaysStrict": ` + value
|
||||
}
|
||||
testCases = append(testCases, &tscInput{
|
||||
subScenario: "alwaysStrict " + value + " in configuration",
|
||||
files: FileMap{
|
||||
"/home/src/workspaces/project/tsconfig.json": fmt.Sprintf(`{"compilerOptions": {"target": "es2015"%s}}`, option),
|
||||
"/home/src/workspaces/project/index.ts": "export {};",
|
||||
},
|
||||
commandLineArgs: []string{"--noEmit"},
|
||||
})
|
||||
}
|
||||
for _, setting := range []struct {
|
||||
name string
|
||||
config string
|
||||
base string
|
||||
}{
|
||||
{"relative", `{"compilerOptions": {"target": "es2015", "baseUrl": "."}}`, ""},
|
||||
{"empty", `{"compilerOptions": {"target": "es2015", "baseUrl": ""}}`, ""},
|
||||
{"inherited", `{"extends": "./base.json"}`, `{"compilerOptions": {"target": "es2015", "baseUrl": "."}}`},
|
||||
{"omitted", `{"compilerOptions": {"target": "es2015"}}`, ""},
|
||||
} {
|
||||
files := FileMap{
|
||||
"/home/src/workspaces/project/tsconfig.json": setting.config,
|
||||
"/home/src/workspaces/project/index.ts": "export {};",
|
||||
}
|
||||
if setting.base != "" {
|
||||
files["/home/src/workspaces/project/base.json"] = setting.base
|
||||
}
|
||||
testCases = append(testCases, &tscInput{
|
||||
subScenario: "baseUrl " + setting.name + " in configuration",
|
||||
files: files,
|
||||
commandLineArgs: []string{"--noEmit"},
|
||||
})
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
testCase.run(t, "commandLine")
|
||||
}
|
||||
@@ -2569,6 +2606,153 @@ func TestTscIncremental(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTscIncrementalDeletion(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, mode := range []struct {
|
||||
name string
|
||||
args []string
|
||||
}{
|
||||
{},
|
||||
{" with single threaded", []string{"--singleThreaded"}},
|
||||
{" with one checker", []string{"--checkers", "1"}},
|
||||
} {
|
||||
config := func(options string) string {
|
||||
return `{"compilerOptions":{"incremental":true,"noEmit":true,"types":[]` + options + `},"files":["a.ts"]}`
|
||||
}
|
||||
(&tscInput{
|
||||
subScenario: "lib and target changes delete mixed library files" + mode.name,
|
||||
commandLineArgs: mode.args,
|
||||
files: FileMap{
|
||||
"/home/src/workspaces/project/tsconfig.json": config(`,"target":"esnext"`),
|
||||
"/home/src/workspaces/project/a.ts": `export const values = [3, 1, 2].toSorted();`,
|
||||
getTestLibPathFor("es5"): tscDefaultLibContent,
|
||||
getTestLibPathFor("esnext.array"): stringtestutil.Dedent(`
|
||||
/// <reference no-default-lib="true"/>
|
||||
interface Array<T> {
|
||||
toSorted(): T[];
|
||||
}
|
||||
`),
|
||||
getTestLibPathFor("decorators"): stringtestutil.Dedent(`
|
||||
/// <reference no-default-lib="true"/>
|
||||
export {};
|
||||
`),
|
||||
getTestLibPathFor("esnext.full"): stringtestutil.Dedent(`
|
||||
/// <reference no-default-lib="true"/>
|
||||
/// <reference lib="es5"/>
|
||||
/// <reference lib="esnext.array"/>
|
||||
/// <reference lib="decorators"/>
|
||||
`),
|
||||
getTestLibPathFor("es2020"): stringtestutil.Dedent(`
|
||||
/// <reference no-default-lib="true"/>
|
||||
/// <reference lib="es5"/>
|
||||
`),
|
||||
getTestLibPathFor("es2020.full"): stringtestutil.Dedent(`
|
||||
/// <reference no-default-lib="true"/>
|
||||
/// <reference lib="es5"/>
|
||||
`),
|
||||
},
|
||||
edits: []*tscEdit{
|
||||
{caption: "narrow lib", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/tsconfig.json", config(`,"target":"esnext","lib":["es2020"]`))
|
||||
}},
|
||||
noChange,
|
||||
{caption: "restore lib", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/tsconfig.json", config(`,"target":"esnext"`))
|
||||
}},
|
||||
{caption: "narrow target", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/tsconfig.json", config(`,"target":"es2020"`))
|
||||
}},
|
||||
noChange,
|
||||
{caption: "restore target", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/tsconfig.json", config(`,"target":"esnext"`))
|
||||
}},
|
||||
noChange,
|
||||
},
|
||||
}).run(t, "incremental")
|
||||
(&tscInput{
|
||||
subScenario: "mixed file deletion with add and change" + mode.name,
|
||||
commandLineArgs: mode.args,
|
||||
files: FileMap{
|
||||
"/home/src/workspaces/project/tsconfig.json": `{"compilerOptions":{"incremental":true,"noEmit":true,"types":[]}}`,
|
||||
"/home/src/workspaces/project/consumer.ts": `declare const value: RemovedGlobal; value.property;`,
|
||||
"/home/src/workspaces/project/global.d.ts": `interface RemovedGlobal { property: string; }`,
|
||||
"/home/src/workspaces/project/module.d.ts": `export interface ModuleOnly { property: string; }`,
|
||||
"/home/src/workspaces/project/changed.ts": `export const changed = 1;`,
|
||||
},
|
||||
edits: []*tscEdit{
|
||||
{caption: "delete global and non-global files while adding and changing sources", edit: func(sys *TestSys) {
|
||||
sys.removeNoError("/home/src/workspaces/project/global.d.ts")
|
||||
sys.removeNoError("/home/src/workspaces/project/module.d.ts")
|
||||
sys.replaceFileText("/home/src/workspaces/project/changed.ts", "1", "2")
|
||||
sys.writeFileNoError("/home/src/workspaces/project/added.ts", `export const added = 1;`)
|
||||
}},
|
||||
noChange,
|
||||
{caption: "restore global file", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/global.d.ts", `interface RemovedGlobal { property: number; }`)
|
||||
}},
|
||||
{caption: "delete ordinary source file", edit: func(sys *TestSys) {
|
||||
sys.removeNoError("/home/src/workspaces/project/added.ts")
|
||||
}},
|
||||
noChange,
|
||||
},
|
||||
}).run(t, "incremental")
|
||||
for _, cleared := range []bool{false, true} {
|
||||
library := tscDefaultLibContent + "\ninterface LibraryConsumer { property: RemovedGlobal; }"
|
||||
global := "interface RemovedGlobal {}"
|
||||
if cleared {
|
||||
library = tscDefaultLibContent + "\ninterface Shared<T> {}"
|
||||
global = "interface Shared<T, U> {}"
|
||||
}
|
||||
(&tscInput{
|
||||
subScenario: fmt.Sprintf("retained library diagnostics after global deletion cleared %t%s", cleared, mode.name),
|
||||
commandLineArgs: mode.args,
|
||||
files: FileMap{
|
||||
"/home/src/workspaces/project/tsconfig.json": `{"compilerOptions":{"incremental":true,"noEmit":true,"types":[],"lib":["es5"]}}`,
|
||||
"/home/src/workspaces/project/consumer.ts": "export const unchanged = 1;",
|
||||
"/home/src/workspaces/project/global.d.ts": global,
|
||||
"/home/src/workspaces/project/module.d.ts": "export interface Unrelated {}",
|
||||
getTestLibPathFor("es5"): library,
|
||||
},
|
||||
edits: []*tscEdit{
|
||||
{caption: "delete global and module declarations", edit: func(sys *TestSys) {
|
||||
sys.removeNoError("/home/src/workspaces/project/global.d.ts")
|
||||
sys.removeNoError("/home/src/workspaces/project/module.d.ts")
|
||||
}},
|
||||
noChange,
|
||||
{caption: "restore global declaration", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/global.d.ts", global)
|
||||
}},
|
||||
noChange,
|
||||
},
|
||||
}).run(t, "incremental")
|
||||
}
|
||||
}
|
||||
for _, composite := range []bool{false, true} {
|
||||
(&tscInput{
|
||||
subScenario: fmt.Sprintf("unchecked deleted paths with no emit composite %t", composite),
|
||||
files: FileMap{
|
||||
"/home/src/workspaces/project/tsconfig.json": fmt.Sprintf(`{"compilerOptions":{"incremental":true,"noCheck":true,"noEmit":true,"composite":%t,"types":[]}}`, composite),
|
||||
"/home/src/workspaces/project/stable.ts": "export const stable = 1;",
|
||||
},
|
||||
edits: []*tscEdit{
|
||||
{caption: "add unchecked sources", edit: func(sys *TestSys) {
|
||||
sys.writeFileNoError("/home/src/workspaces/project/first.ts", "export const first = 1;")
|
||||
sys.writeFileNoError("/home/src/workspaces/project/second.ts", "export const second = 1;")
|
||||
}},
|
||||
{caption: "delete unchecked sources", edit: func(sys *TestSys) {
|
||||
sys.removeNoError("/home/src/workspaces/project/first.ts")
|
||||
sys.removeNoError("/home/src/workspaces/project/second.ts")
|
||||
}},
|
||||
noChange,
|
||||
{caption: "enable checking and emit", edit: func(sys *TestSys) {
|
||||
sys.replaceFileText("/home/src/workspaces/project/tsconfig.json", `"noCheck":true,"noEmit":true`, `"noCheck":false,"noEmit":false`)
|
||||
}},
|
||||
noChange,
|
||||
},
|
||||
}).run(t, "incremental")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTscLibraryResolution(t *testing.T) {
|
||||
t.Parallel()
|
||||
getTscLibraryResolutionFileMap := func(libReplacement bool) FileMap {
|
||||
|
||||
@@ -85,6 +85,8 @@ func (o *RawCompilerOptions) Finalize(basePath tspath.RootedDirectoryPath) (*cor
|
||||
}
|
||||
} else if key == "configFilePath" {
|
||||
pathKind = CommandLineOptionPathKindFile
|
||||
} else if key == "pathsBasePath" {
|
||||
pathKind = CommandLineOptionPathKindDirectory
|
||||
} else if key != "allowNonTsExtensions" && key != "suppressOutputPathCheck" {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ func TestRawCompilerOptionsFinalizePaths(t *testing.T) {
|
||||
"allowNonTsExtensions": true,
|
||||
"suppressOutputPathCheck": true,
|
||||
"configFilePath": "",
|
||||
"pathsBasePath": "config",
|
||||
"NoImplicitAny": true
|
||||
}`), &raw))
|
||||
|
||||
@@ -46,5 +47,6 @@ func TestRawCompilerOptionsFinalizePaths(t *testing.T) {
|
||||
assert.Equal(t, options.AllowNonTsExtensions, core.TSTrue)
|
||||
assert.Equal(t, options.SuppressOutputPathCheck, core.TSTrue)
|
||||
assert.Equal(t, options.ConfigFilePath, tspath.RootedFilePath(""))
|
||||
assert.Equal(t, options.PathsBasePath, tspath.RootedDirectoryPath("/project/config"))
|
||||
assert.Equal(t, options.NoImplicitAny, core.TSUnknown)
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
//// [tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts] ////
|
||||
|
||||
=== assertedGenericPartialIndexedAssignment.ts ===
|
||||
function write<T extends Record<string, unknown>>(values: Partial<T>, key: string) {
|
||||
>write : Symbol(write, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 15))
|
||||
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
|
||||
>values : Symbol(values, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 50))
|
||||
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 15))
|
||||
>key : Symbol(key, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 69))
|
||||
|
||||
(values[key] as unknown) = 0;
|
||||
>values : Symbol(values, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 50))
|
||||
>key : Symbol(key, Decl(assertedGenericPartialIndexedAssignment.ts, 0, 69))
|
||||
}
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
//// [tests/cases/compiler/assertedGenericPartialIndexedAssignment.ts] ////
|
||||
|
||||
=== assertedGenericPartialIndexedAssignment.ts ===
|
||||
function write<T extends Record<string, unknown>>(values: Partial<T>, key: string) {
|
||||
>write : <T extends Record<string, unknown>>(values: Partial<T>, key: string) => void
|
||||
>values : Partial<T>
|
||||
>key : string
|
||||
|
||||
(values[key] as unknown) = 0;
|
||||
>(values[key] as unknown) = 0 : 0
|
||||
>(values[key] as unknown) : unknown
|
||||
>values[key] as unknown : unknown
|
||||
>values[key] : T[string] | undefined
|
||||
>values : Partial<T>
|
||||
>key : string
|
||||
>0 : 0
|
||||
}
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts] ////
|
||||
|
||||
=== assertedReadonlyParameterPropertyAssignment.ts ===
|
||||
class ReadonlyState {
|
||||
>ReadonlyState : Symbol(ReadonlyState, Decl(assertedReadonlyParameterPropertyAssignment.ts, 0, 0))
|
||||
|
||||
constructor(readonly value: object) {}
|
||||
>value : Symbol(ReadonlyState.value, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 16))
|
||||
|
||||
clear() {
|
||||
>clear : Symbol(ReadonlyState.clear, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 42))
|
||||
|
||||
(this.value as unknown) = null;
|
||||
>this.value : Symbol(ReadonlyState.value, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 16))
|
||||
>this : Symbol(ReadonlyState, Decl(assertedReadonlyParameterPropertyAssignment.ts, 0, 0))
|
||||
>value : Symbol(ReadonlyState.value, Decl(assertedReadonlyParameterPropertyAssignment.ts, 1, 16))
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
//// [tests/cases/compiler/assertedReadonlyParameterPropertyAssignment.ts] ////
|
||||
|
||||
=== assertedReadonlyParameterPropertyAssignment.ts ===
|
||||
class ReadonlyState {
|
||||
>ReadonlyState : ReadonlyState
|
||||
|
||||
constructor(readonly value: object) {}
|
||||
>value : object
|
||||
|
||||
clear() {
|
||||
>clear : () => void
|
||||
|
||||
(this.value as unknown) = null;
|
||||
>(this.value as unknown) = null : null
|
||||
>(this.value as unknown) : unknown
|
||||
>this.value as unknown : unknown
|
||||
>this.value : object
|
||||
>this : this
|
||||
>value : object
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
//// [tests/cases/compiler/callableConstructorUnionMetadata.ts] ////
|
||||
|
||||
=== callableConstructorUnionMetadata.ts ===
|
||||
type Component<Props> = ((props: Props) => number) | (new (props: Props) => object);
|
||||
>Component : Symbol(Component, Decl(callableConstructorUnionMetadata.ts, 0, 0))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 0, 15))
|
||||
>props : Symbol(props, Decl(callableConstructorUnionMetadata.ts, 0, 26))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 0, 15))
|
||||
>props : Symbol(props, Decl(callableConstructorUnionMetadata.ts, 0, 59))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 0, 15))
|
||||
|
||||
type Field<Props> = Component<Props> & { testIds?: {} };
|
||||
>Field : Symbol(Field, Decl(callableConstructorUnionMetadata.ts, 0, 84))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 1, 11))
|
||||
>Component : Symbol(Component, Decl(callableConstructorUnionMetadata.ts, 0, 0))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 1, 11))
|
||||
>testIds : Symbol(testIds, Decl(callableConstructorUnionMetadata.ts, 1, 40))
|
||||
|
||||
declare const component: <Props>(props: Props) => number;
|
||||
>component : Symbol(component, Decl(callableConstructorUnionMetadata.ts, 3, 13))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 3, 26))
|
||||
>props : Symbol(props, Decl(callableConstructorUnionMetadata.ts, 3, 33))
|
||||
>Props : Symbol(Props, Decl(callableConstructorUnionMetadata.ts, 3, 26))
|
||||
|
||||
const field: Field<string> = component;
|
||||
>field : Symbol(field, Decl(callableConstructorUnionMetadata.ts, 4, 5))
|
||||
>Field : Symbol(Field, Decl(callableConstructorUnionMetadata.ts, 0, 84))
|
||||
>component : Symbol(component, Decl(callableConstructorUnionMetadata.ts, 3, 13))
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
//// [tests/cases/compiler/callableConstructorUnionMetadata.ts] ////
|
||||
|
||||
=== callableConstructorUnionMetadata.ts ===
|
||||
type Component<Props> = ((props: Props) => number) | (new (props: Props) => object);
|
||||
>Component : Component<Props>
|
||||
>props : Props
|
||||
>props : Props
|
||||
|
||||
type Field<Props> = Component<Props> & { testIds?: {} };
|
||||
>Field : Field<Props>
|
||||
>testIds : {} | undefined
|
||||
|
||||
declare const component: <Props>(props: Props) => number;
|
||||
>component : <Props>(props: Props) => number
|
||||
>props : Props
|
||||
|
||||
const field: Field<string> = component;
|
||||
>field : Field<string>
|
||||
>component : <Props>(props: Props) => number
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
//// [tests/cases/compiler/callableWeakMetadata.ts] ////
|
||||
|
||||
=== callableWeakMetadata.ts ===
|
||||
type Initializer = (() => number) & { mutators?: [] };
|
||||
>Initializer : Symbol(Initializer, Decl(callableWeakMetadata.ts, 0, 0))
|
||||
>mutators : Symbol(mutators, Decl(callableWeakMetadata.ts, 0, 37))
|
||||
|
||||
declare function createStore(initializer: Initializer): void;
|
||||
>createStore : Symbol(createStore, Decl(callableWeakMetadata.ts, 0, 54))
|
||||
>initializer : Symbol(initializer, Decl(callableWeakMetadata.ts, 2, 29))
|
||||
>Initializer : Symbol(Initializer, Decl(callableWeakMetadata.ts, 0, 0))
|
||||
|
||||
createStore(() => 1);
|
||||
>createStore : Symbol(createStore, Decl(callableWeakMetadata.ts, 0, 54))
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
//// [tests/cases/compiler/callableWeakMetadata.ts] ////
|
||||
|
||||
=== callableWeakMetadata.ts ===
|
||||
type Initializer = (() => number) & { mutators?: [] };
|
||||
>Initializer : Initializer
|
||||
>mutators : [] | undefined
|
||||
|
||||
declare function createStore(initializer: Initializer): void;
|
||||
>createStore : (initializer: Initializer) => void
|
||||
>initializer : Initializer
|
||||
|
||||
createStore(() => 1);
|
||||
>createStore(() => 1) : void
|
||||
>createStore : (initializer: Initializer) => void
|
||||
>() => 1 : () => number
|
||||
>1 : 1
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/callableWeakMetadataCallSuggestion.ts] ////
|
||||
|
||||
=== callableWeakMetadataCallSuggestion.ts ===
|
||||
type Initializer = (() => number) & { mutators?: [] };
|
||||
>Initializer : Symbol(Initializer, Decl(callableWeakMetadataCallSuggestion.ts, 0, 0))
|
||||
>mutators : Symbol(mutators, Decl(callableWeakMetadataCallSuggestion.ts, 0, 37))
|
||||
|
||||
declare function createStore(initializer: Initializer): void;
|
||||
>createStore : Symbol(createStore, Decl(callableWeakMetadataCallSuggestion.ts, 0, 54))
|
||||
>initializer : Symbol(initializer, Decl(callableWeakMetadataCallSuggestion.ts, 2, 29))
|
||||
>Initializer : Symbol(Initializer, Decl(callableWeakMetadataCallSuggestion.ts, 0, 0))
|
||||
|
||||
declare const initializer: () => any;
|
||||
>initializer : Symbol(initializer, Decl(callableWeakMetadataCallSuggestion.ts, 3, 13))
|
||||
|
||||
createStore(initializer);
|
||||
>createStore : Symbol(createStore, Decl(callableWeakMetadataCallSuggestion.ts, 0, 54))
|
||||
>initializer : Symbol(initializer, Decl(callableWeakMetadataCallSuggestion.ts, 3, 13))
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/callableWeakMetadataCallSuggestion.ts] ////
|
||||
|
||||
=== callableWeakMetadataCallSuggestion.ts ===
|
||||
type Initializer = (() => number) & { mutators?: [] };
|
||||
>Initializer : Initializer
|
||||
>mutators : [] | undefined
|
||||
|
||||
declare function createStore(initializer: Initializer): void;
|
||||
>createStore : (initializer: Initializer) => void
|
||||
>initializer : Initializer
|
||||
|
||||
declare const initializer: () => any;
|
||||
>initializer : () => any
|
||||
|
||||
createStore(initializer);
|
||||
>createStore(initializer) : void
|
||||
>createStore : (initializer: Initializer) => void
|
||||
>initializer : () => any
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//// [tests/cases/compiler/callbackAssignedNonNull.ts] ////
|
||||
|
||||
=== callbackAssignedNonNull.ts ===
|
||||
declare function initialize(callback: (cancel: () => void) => void): void;
|
||||
>initialize : Symbol(initialize, Decl(callbackAssignedNonNull.ts, 0, 0))
|
||||
>callback : Symbol(callback, Decl(callbackAssignedNonNull.ts, 0, 28))
|
||||
>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 0, 39))
|
||||
|
||||
function start() {
|
||||
>start : Symbol(start, Decl(callbackAssignedNonNull.ts, 0, 74))
|
||||
|
||||
let cancel;
|
||||
>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 3, 7))
|
||||
|
||||
initialize(value => {
|
||||
>initialize : Symbol(initialize, Decl(callbackAssignedNonNull.ts, 0, 0))
|
||||
>value : Symbol(value, Decl(callbackAssignedNonNull.ts, 4, 15))
|
||||
|
||||
cancel = value;
|
||||
>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 3, 7))
|
||||
>value : Symbol(value, Decl(callbackAssignedNonNull.ts, 4, 15))
|
||||
|
||||
});
|
||||
cancel!();
|
||||
>cancel : Symbol(cancel, Decl(callbackAssignedNonNull.ts, 3, 7))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/callbackAssignedNonNull.ts] ////
|
||||
|
||||
=== callbackAssignedNonNull.ts ===
|
||||
declare function initialize(callback: (cancel: () => void) => void): void;
|
||||
>initialize : (callback: (cancel: () => void) => void) => void
|
||||
>callback : (cancel: () => void) => void
|
||||
>cancel : () => void
|
||||
|
||||
function start() {
|
||||
>start : () => void
|
||||
|
||||
let cancel;
|
||||
>cancel : any
|
||||
|
||||
initialize(value => {
|
||||
>initialize(value => { cancel = value; }) : void
|
||||
>initialize : (callback: (cancel: () => void) => void) => void
|
||||
>value => { cancel = value; } : (value: () => void) => void
|
||||
>value : () => void
|
||||
|
||||
cancel = value;
|
||||
>cancel = value : () => void
|
||||
>cancel : any
|
||||
>value : () => void
|
||||
|
||||
});
|
||||
cancel!();
|
||||
>cancel!() : any
|
||||
>cancel! : any
|
||||
>cancel : any
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
//// [tests/cases/compiler/chainedFilterPredicateInference.ts] ////
|
||||
|
||||
//// [chainedFilterPredicateInference.ts]
|
||||
declare const items: { id: number }[];
|
||||
declare const registry: { [id: number]: { [frame: number]: unknown } };
|
||||
|
||||
items
|
||||
.filter(item => true)
|
||||
.filter(item => !registry[item.id])
|
||||
.forEach(item => item.id);
|
||||
|
||||
|
||||
//// [chainedFilterPredicateInference.js]
|
||||
"use strict";
|
||||
items
|
||||
.filter(item => true)
|
||||
.filter(item => !registry[item.id])
|
||||
.forEach(item => item.id);
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
//// [tests/cases/compiler/chainedFilterPredicateInference.ts] ////
|
||||
|
||||
=== chainedFilterPredicateInference.ts ===
|
||||
declare const items: { id: number }[];
|
||||
>items : Symbol(items, Decl(chainedFilterPredicateInference.ts, 0, 13))
|
||||
>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22))
|
||||
|
||||
declare const registry: { [id: number]: { [frame: number]: unknown } };
|
||||
>registry : Symbol(registry, Decl(chainedFilterPredicateInference.ts, 1, 13))
|
||||
>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 1, 27))
|
||||
>frame : Symbol(frame, Decl(chainedFilterPredicateInference.ts, 1, 43))
|
||||
|
||||
items
|
||||
>items .filter(item => true) .filter(item => !registry[item.id]) .forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --))
|
||||
>items .filter(item => true) .filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>items .filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>items : Symbol(items, Decl(chainedFilterPredicateInference.ts, 0, 13))
|
||||
|
||||
.filter(item => true)
|
||||
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 4, 12))
|
||||
|
||||
.filter(item => !registry[item.id])
|
||||
>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 5, 12))
|
||||
>registry : Symbol(registry, Decl(chainedFilterPredicateInference.ts, 1, 13))
|
||||
>item.id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22))
|
||||
>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 5, 12))
|
||||
>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22))
|
||||
|
||||
.forEach(item => item.id);
|
||||
>forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --))
|
||||
>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 6, 13))
|
||||
>item.id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22))
|
||||
>item : Symbol(item, Decl(chainedFilterPredicateInference.ts, 6, 13))
|
||||
>id : Symbol(id, Decl(chainedFilterPredicateInference.ts, 0, 22))
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//// [tests/cases/compiler/chainedFilterPredicateInference.ts] ////
|
||||
|
||||
=== chainedFilterPredicateInference.ts ===
|
||||
declare const items: { id: number }[];
|
||||
>items : { id: number; }[]
|
||||
>id : number
|
||||
|
||||
declare const registry: { [id: number]: { [frame: number]: unknown } };
|
||||
>registry : { [id: number]: { [frame: number]: unknown; }; }
|
||||
>id : number
|
||||
>frame : number
|
||||
|
||||
items
|
||||
>items .filter(item => true) .filter(item => !registry[item.id]) .forEach(item => item.id) : void
|
||||
>items .filter(item => true) .filter(item => !registry[item.id]) .forEach : (callbackfn: (value: { id: number; }, index: number, array: { id: number; }[]) => void, thisArg?: any) => void
|
||||
>items .filter(item => true) .filter(item => !registry[item.id]) : { id: number; }[]
|
||||
>items .filter(item => true) .filter : { <S extends { id: number; }>(predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; }
|
||||
>items .filter(item => true) : { id: number; }[]
|
||||
>items .filter : { <S extends { id: number; }>(predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; }
|
||||
>items : { id: number; }[]
|
||||
|
||||
.filter(item => true)
|
||||
>filter : { <S extends { id: number; }>(predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; }
|
||||
>item => true : (item: { id: number; }) => true
|
||||
>item : { id: number; }
|
||||
>true : true
|
||||
|
||||
.filter(item => !registry[item.id])
|
||||
>filter : { <S extends { id: number; }>(predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => value is S, thisArg?: any): S[]; (predicate: (value: { id: number; }, index: number, array: { id: number; }[]) => unknown, thisArg?: any): { id: number; }[]; }
|
||||
>item => !registry[item.id] : (item: { id: number; }) => false
|
||||
>item : { id: number; }
|
||||
>!registry[item.id] : false
|
||||
>registry[item.id] : { [frame: number]: unknown; }
|
||||
>registry : { [id: number]: { [frame: number]: unknown; }; }
|
||||
>item.id : number
|
||||
>item : { id: number; }
|
||||
>id : number
|
||||
|
||||
.forEach(item => item.id);
|
||||
>forEach : (callbackfn: (value: { id: number; }, index: number, array: { id: number; }[]) => void, thisArg?: any) => void
|
||||
>item => item.id : (item: { id: number; }) => number
|
||||
>item : { id: number; }
|
||||
>item.id : number
|
||||
>item : { id: number; }
|
||||
>id : number
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
//// [tests/cases/compiler/componentEnhancerReturn.ts] ////
|
||||
|
||||
=== componentEnhancerReturn.ts ===
|
||||
type Component = ((props: number) => number) | (new (props: number) => object);
|
||||
>Component : Symbol(Component, Decl(componentEnhancerReturn.ts, 0, 0))
|
||||
>props : Symbol(props, Decl(componentEnhancerReturn.ts, 0, 19))
|
||||
>props : Symbol(props, Decl(componentEnhancerReturn.ts, 0, 53))
|
||||
|
||||
type App = Component & { getInitialProps?: () => object };
|
||||
>App : Symbol(App, Decl(componentEnhancerReturn.ts, 0, 79))
|
||||
>Component : Symbol(Component, Decl(componentEnhancerReturn.ts, 0, 0))
|
||||
>getInitialProps : Symbol(getInitialProps, Decl(componentEnhancerReturn.ts, 1, 24))
|
||||
|
||||
declare function render(enhance: (app: App) => App): void;
|
||||
>render : Symbol(render, Decl(componentEnhancerReturn.ts, 1, 58))
|
||||
>enhance : Symbol(enhance, Decl(componentEnhancerReturn.ts, 2, 24))
|
||||
>app : Symbol(app, Decl(componentEnhancerReturn.ts, 2, 34))
|
||||
>App : Symbol(App, Decl(componentEnhancerReturn.ts, 0, 79))
|
||||
>App : Symbol(App, Decl(componentEnhancerReturn.ts, 0, 79))
|
||||
|
||||
render(app => props => props);
|
||||
>render : Symbol(render, Decl(componentEnhancerReturn.ts, 1, 58))
|
||||
>app : Symbol(app, Decl(componentEnhancerReturn.ts, 3, 7))
|
||||
>props : Symbol(props, Decl(componentEnhancerReturn.ts, 3, 13))
|
||||
>props : Symbol(props, Decl(componentEnhancerReturn.ts, 3, 13))
|
||||
|
||||
interface RenderPlugin { enhance(app: Component): (props: number) => number }
|
||||
>RenderPlugin : Symbol(RenderPlugin, Decl(componentEnhancerReturn.ts, 3, 30))
|
||||
>enhance : Symbol(RenderPlugin.enhance, Decl(componentEnhancerReturn.ts, 5, 24))
|
||||
>app : Symbol(app, Decl(componentEnhancerReturn.ts, 5, 33))
|
||||
>Component : Symbol(Component, Decl(componentEnhancerReturn.ts, 0, 0))
|
||||
>props : Symbol(props, Decl(componentEnhancerReturn.ts, 5, 51))
|
||||
|
||||
declare const plugins: RenderPlugin[];
|
||||
>plugins : Symbol(plugins, Decl(componentEnhancerReturn.ts, 6, 13))
|
||||
>RenderPlugin : Symbol(RenderPlugin, Decl(componentEnhancerReturn.ts, 3, 30))
|
||||
|
||||
render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app));
|
||||
>render : Symbol(render, Decl(componentEnhancerReturn.ts, 1, 58))
|
||||
>app : Symbol(app, Decl(componentEnhancerReturn.ts, 7, 7))
|
||||
>plugins.reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>plugins : Symbol(plugins, Decl(componentEnhancerReturn.ts, 6, 13))
|
||||
>reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(componentEnhancerReturn.ts, 7, 30))
|
||||
>plugin : Symbol(plugin, Decl(componentEnhancerReturn.ts, 7, 37))
|
||||
>plugin.enhance : Symbol(RenderPlugin.enhance, Decl(componentEnhancerReturn.ts, 5, 24))
|
||||
>plugin : Symbol(plugin, Decl(componentEnhancerReturn.ts, 7, 37))
|
||||
>enhance : Symbol(RenderPlugin.enhance, Decl(componentEnhancerReturn.ts, 5, 24))
|
||||
>result : Symbol(result, Decl(componentEnhancerReturn.ts, 7, 30))
|
||||
>app : Symbol(app, Decl(componentEnhancerReturn.ts, 7, 7))
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
//// [tests/cases/compiler/componentEnhancerReturn.ts] ////
|
||||
|
||||
=== componentEnhancerReturn.ts ===
|
||||
type Component = ((props: number) => number) | (new (props: number) => object);
|
||||
>Component : Component
|
||||
>props : number
|
||||
>props : number
|
||||
|
||||
type App = Component & { getInitialProps?: () => object };
|
||||
>App : App
|
||||
>getInitialProps : (() => object) | undefined
|
||||
|
||||
declare function render(enhance: (app: App) => App): void;
|
||||
>render : (enhance: (app: App) => App) => void
|
||||
>enhance : (app: App) => App
|
||||
>app : App
|
||||
|
||||
render(app => props => props);
|
||||
>render(app => props => props) : void
|
||||
>render : (enhance: (app: App) => App) => void
|
||||
>app => props => props : (app: App) => (props: number) => number
|
||||
>app : App
|
||||
>props => props : (props: number) => number
|
||||
>props : number
|
||||
>props : number
|
||||
|
||||
interface RenderPlugin { enhance(app: Component): (props: number) => number }
|
||||
>enhance : (app: Component) => (props: number) => number
|
||||
>app : Component
|
||||
>props : number
|
||||
|
||||
declare const plugins: RenderPlugin[];
|
||||
>plugins : RenderPlugin[]
|
||||
|
||||
render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app));
|
||||
>render(app => plugins.reduce((result, plugin) => plugin.enhance(result), app)) : void
|
||||
>render : (enhance: (app: App) => App) => void
|
||||
>app => plugins.reduce((result, plugin) => plugin.enhance(result), app) : (app: App) => App
|
||||
>app : App
|
||||
>plugins.reduce((result, plugin) => plugin.enhance(result), app) : App
|
||||
>plugins.reduce : { (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin): RenderPlugin; (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin, initialValue: RenderPlugin): RenderPlugin; <U>(callbackfn: (previousValue: U, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => U, initialValue: U): U; }
|
||||
>plugins : RenderPlugin[]
|
||||
>reduce : { (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin): RenderPlugin; (callbackfn: (previousValue: RenderPlugin, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => RenderPlugin, initialValue: RenderPlugin): RenderPlugin; <U>(callbackfn: (previousValue: U, currentValue: RenderPlugin, currentIndex: number, array: RenderPlugin[]) => U, initialValue: U): U; }
|
||||
>(result, plugin) => plugin.enhance(result) : (result: App, plugin: RenderPlugin) => (props: number) => number
|
||||
>result : App
|
||||
>plugin : RenderPlugin
|
||||
>plugin.enhance(result) : (props: number) => number
|
||||
>plugin.enhance : (app: Component) => (props: number) => number
|
||||
>plugin : RenderPlugin
|
||||
>enhance : (app: Component) => (props: number) => number
|
||||
>result : App
|
||||
>app : App
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
//// [tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts] ////
|
||||
|
||||
//// [compoundAssignmentAfterExcludedLiteral.ts]
|
||||
function append(buffer: { value: string }) {
|
||||
if (buffer.value !== "") {
|
||||
buffer.value += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [compoundAssignmentAfterExcludedLiteral.js]
|
||||
"use strict";
|
||||
function append(buffer) {
|
||||
if (buffer.value !== "") {
|
||||
buffer.value += "\n";
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
//// [tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts] ////
|
||||
|
||||
=== compoundAssignmentAfterExcludedLiteral.ts ===
|
||||
function append(buffer: { value: string }) {
|
||||
>append : Symbol(append, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 0))
|
||||
>buffer : Symbol(buffer, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 16))
|
||||
>value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25))
|
||||
|
||||
if (buffer.value !== "") {
|
||||
>buffer.value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25))
|
||||
>buffer : Symbol(buffer, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 16))
|
||||
>value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25))
|
||||
|
||||
buffer.value += "\n";
|
||||
>buffer.value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25))
|
||||
>buffer : Symbol(buffer, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 16))
|
||||
>value : Symbol(value, Decl(compoundAssignmentAfterExcludedLiteral.ts, 0, 25))
|
||||
}
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
//// [tests/cases/compiler/compoundAssignmentAfterExcludedLiteral.ts] ////
|
||||
|
||||
=== compoundAssignmentAfterExcludedLiteral.ts ===
|
||||
function append(buffer: { value: string }) {
|
||||
>append : (buffer: { value: string; }) => void
|
||||
>buffer : { value: string; }
|
||||
>value : string
|
||||
|
||||
if (buffer.value !== "") {
|
||||
>buffer.value !== "" : boolean
|
||||
>buffer.value : string
|
||||
>buffer : { value: string; }
|
||||
>value : string
|
||||
>"" : ""
|
||||
|
||||
buffer.value += "\n";
|
||||
>buffer.value += "\n" : string
|
||||
>buffer.value : string
|
||||
>buffer : { value: string; }
|
||||
>value : string
|
||||
>"\n" : "\n"
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
//// [tests/cases/compiler/conditionalExportsNodeTypesFallback.ts] ////
|
||||
|
||||
=== /index.mts ===
|
||||
import { value } from "provider";
|
||||
>value : Symbol(value, Decl(index.mts, 0, 8))
|
||||
|
||||
value;
|
||||
>value : Symbol(value, Decl(index.mts, 0, 8))
|
||||
|
||||
=== /node_modules/provider/types.d.ts ===
|
||||
export const value: number;
|
||||
>value : Symbol(value, Decl(types.d.ts, 0, 12))
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
======== Resolving module 'provider' from '/index.mts'. ========
|
||||
Explicitly specified module resolution kind: 'NodeNext'.
|
||||
Resolving in ESM mode with conditions 'import', 'types', 'node'.
|
||||
File '/package.json' does not exist.
|
||||
Loading module 'provider' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
|
||||
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
|
||||
Found 'package.json' at '/node_modules/provider/package.json'.
|
||||
Entering conditional exports.
|
||||
Matched 'exports' condition 'node'.
|
||||
Using 'exports' subpath '.' with target './index.js'.
|
||||
File name '/node_modules/provider/index.js' has a '.js' extension - stripping it.
|
||||
File '/node_modules/provider/index.ts' does not exist.
|
||||
File '/node_modules/provider/index.tsx' does not exist.
|
||||
File '/node_modules/provider/index.d.ts' does not exist.
|
||||
Failed to resolve under condition 'node'.
|
||||
Matched 'exports' condition 'types'.
|
||||
Using 'exports' subpath '.' with target './types.d.ts'.
|
||||
File '/node_modules/provider/types.d.ts' exists - use it as a name resolution result.
|
||||
Resolved under condition 'types'.
|
||||
Exiting conditional exports.
|
||||
Resolving real path for '/node_modules/provider/types.d.ts', result '/node_modules/provider/types.d.ts'.
|
||||
======== Module name 'provider' was successfully resolved to '/node_modules/provider/types.d.ts'. ========
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
//// [tests/cases/compiler/conditionalExportsNodeTypesFallback.ts] ////
|
||||
|
||||
=== /index.mts ===
|
||||
import { value } from "provider";
|
||||
>value : number
|
||||
|
||||
value;
|
||||
>value : number
|
||||
|
||||
=== /node_modules/provider/types.d.ts ===
|
||||
export const value: number;
|
||||
>value : number
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
//// [tests/cases/compiler/conditionalExportsRequireTypesFallback.ts] ////
|
||||
|
||||
=== /index.cts ===
|
||||
import { value } from "provider";
|
||||
>value : Symbol(value, Decl(index.cts, 0, 8))
|
||||
|
||||
value;
|
||||
>value : Symbol(value, Decl(index.cts, 0, 8))
|
||||
|
||||
=== /node_modules/provider/index.d.ts ===
|
||||
export const value: number;
|
||||
>value : Symbol(value, Decl(index.d.ts, 0, 12))
|
||||
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
======== Resolving module 'provider' from '/index.cts'. ========
|
||||
Explicitly specified module resolution kind: 'NodeNext'.
|
||||
Resolving in CJS mode with conditions 'require', 'types', 'node'.
|
||||
File '/package.json' does not exist.
|
||||
Loading module 'provider' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
|
||||
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
|
||||
Found 'package.json' at '/node_modules/provider/package.json'.
|
||||
Entering conditional exports.
|
||||
Matched 'exports' condition 'require'.
|
||||
Using 'exports' subpath '.' with target './index.cjs'.
|
||||
File name '/node_modules/provider/index.cjs' has a '.cjs' extension - stripping it.
|
||||
File '/node_modules/provider/index.cts' does not exist.
|
||||
File '/node_modules/provider/index.d.cts' does not exist.
|
||||
Failed to resolve under condition 'require'.
|
||||
Matched 'exports' condition 'types'.
|
||||
Using 'exports' subpath '.' with target './index.d.ts'.
|
||||
File '/node_modules/provider/index.d.ts' exists - use it as a name resolution result.
|
||||
Resolved under condition 'types'.
|
||||
Exiting conditional exports.
|
||||
Resolving real path for '/node_modules/provider/index.d.ts', result '/node_modules/provider/index.d.ts'.
|
||||
======== Module name 'provider' was successfully resolved to '/node_modules/provider/index.d.ts'. ========
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
//// [tests/cases/compiler/conditionalExportsRequireTypesFallback.ts] ////
|
||||
|
||||
=== /index.cts ===
|
||||
import { value } from "provider";
|
||||
>value : number
|
||||
|
||||
value;
|
||||
>value : number
|
||||
|
||||
=== /node_modules/provider/index.d.ts ===
|
||||
export const value: number;
|
||||
>value : number
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/conditionalExportsTypesImportFallback.ts] ////
|
||||
|
||||
=== /index.mts ===
|
||||
import color from "theme/tokens";
|
||||
>color : Symbol(color, Decl(index.mts, 0, 6))
|
||||
|
||||
color;
|
||||
>color : Symbol(color, Decl(index.mts, 0, 6))
|
||||
|
||||
=== /node_modules/theme/tokens.d.mts ===
|
||||
declare const color: string;
|
||||
>color : Symbol(color, Decl(tokens.d.mts, 0, 13))
|
||||
|
||||
export default color;
|
||||
>color : Symbol(color, Decl(tokens.d.mts, 0, 13))
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
======== Resolving module 'theme/tokens' from '/index.mts'. ========
|
||||
Explicitly specified module resolution kind: 'Bundler'.
|
||||
Resolving in CJS mode with conditions 'import', 'types'.
|
||||
File '/package.json' does not exist.
|
||||
Loading module 'theme/tokens' from 'node_modules' folder, target file types: TypeScript, JavaScript, Declaration, JSON.
|
||||
Searching all ancestor node_modules directories for preferred extensions: TypeScript, Declaration.
|
||||
Found 'package.json' at '/node_modules/theme/package.json'.
|
||||
Entering conditional exports.
|
||||
Matched 'exports' condition 'types'.
|
||||
Using 'exports' subpath './tokens' with target './tokens.d.ts'.
|
||||
File '/node_modules/theme/tokens.d.ts' does not exist.
|
||||
Failed to resolve under condition 'types'.
|
||||
Matched 'exports' condition 'import'.
|
||||
Using 'exports' subpath './tokens' with target './tokens.mjs'.
|
||||
File name '/node_modules/theme/tokens.mjs' has a '.mjs' extension - stripping it.
|
||||
File '/node_modules/theme/tokens.mts' does not exist.
|
||||
File '/node_modules/theme/tokens.d.mts' exists - use it as a name resolution result.
|
||||
Resolved under condition 'import'.
|
||||
Exiting conditional exports.
|
||||
Resolving real path for '/node_modules/theme/tokens.d.mts', result '/node_modules/theme/tokens.d.mts'.
|
||||
======== Module name 'theme/tokens' was successfully resolved to '/node_modules/theme/tokens.d.mts'. ========
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/conditionalExportsTypesImportFallback.ts] ////
|
||||
|
||||
=== /index.mts ===
|
||||
import color from "theme/tokens";
|
||||
>color : string
|
||||
|
||||
color;
|
||||
>color : string
|
||||
|
||||
=== /node_modules/theme/tokens.d.mts ===
|
||||
declare const color: string;
|
||||
>color : string
|
||||
|
||||
export default color;
|
||||
>color : string
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
//// [tests/cases/compiler/conditionalFunctionUnionInference.ts] ////
|
||||
|
||||
=== conditionalFunctionUnionInference.ts ===
|
||||
type DeepValue<T> = T extends () => unknown ? T :
|
||||
>DeepValue : Symbol(DeepValue, Decl(conditionalFunctionUnionInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15))
|
||||
|
||||
{ [K in keyof T]: DeepValue<T[K]> };
|
||||
>K : Symbol(K, Decl(conditionalFunctionUnionInference.ts, 1, 7))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15))
|
||||
>DeepValue : Symbol(DeepValue, Decl(conditionalFunctionUnionInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 0, 15))
|
||||
>K : Symbol(K, Decl(conditionalFunctionUnionInference.ts, 1, 7))
|
||||
|
||||
declare function createValue<T>(initialValue: DeepValue<T | (() => T)>): T;
|
||||
>createValue : Symbol(createValue, Decl(conditionalFunctionUnionInference.ts, 1, 40))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29))
|
||||
>initialValue : Symbol(initialValue, Decl(conditionalFunctionUnionInference.ts, 3, 32))
|
||||
>DeepValue : Symbol(DeepValue, Decl(conditionalFunctionUnionInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29))
|
||||
>T : Symbol(T, Decl(conditionalFunctionUnionInference.ts, 3, 29))
|
||||
|
||||
const value = createValue(() => ({ ready: true }));
|
||||
>value : Symbol(value, Decl(conditionalFunctionUnionInference.ts, 5, 5))
|
||||
>createValue : Symbol(createValue, Decl(conditionalFunctionUnionInference.ts, 1, 40))
|
||||
>ready : Symbol(ready, Decl(conditionalFunctionUnionInference.ts, 5, 34))
|
||||
|
||||
value.ready;
|
||||
>value.ready : Symbol(ready, Decl(conditionalFunctionUnionInference.ts, 5, 34))
|
||||
>value : Symbol(value, Decl(conditionalFunctionUnionInference.ts, 5, 5))
|
||||
>ready : Symbol(ready, Decl(conditionalFunctionUnionInference.ts, 5, 34))
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
//// [tests/cases/compiler/conditionalFunctionUnionInference.ts] ////
|
||||
|
||||
=== conditionalFunctionUnionInference.ts ===
|
||||
type DeepValue<T> = T extends () => unknown ? T :
|
||||
>DeepValue : DeepValue<T>
|
||||
|
||||
{ [K in keyof T]: DeepValue<T[K]> };
|
||||
|
||||
declare function createValue<T>(initialValue: DeepValue<T | (() => T)>): T;
|
||||
>createValue : <T>(initialValue: DeepValue<T | (() => T)>) => T
|
||||
>initialValue : (() => T) | DeepValue<T>
|
||||
|
||||
const value = createValue(() => ({ ready: true }));
|
||||
>value : { ready: boolean; }
|
||||
>createValue(() => ({ ready: true })) : { ready: boolean; }
|
||||
>createValue : <T>(initialValue: DeepValue<T | (() => T)>) => T
|
||||
>() => ({ ready: true }) : () => { ready: boolean; }
|
||||
>({ ready: true }) : { ready: true; }
|
||||
>{ ready: true } : { ready: true; }
|
||||
>ready : true
|
||||
>true : true
|
||||
|
||||
value.ready;
|
||||
>value.ready : boolean
|
||||
>value : { ready: boolean; }
|
||||
>ready : boolean
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
//// [tests/cases/compiler/conditionalPromptInference.ts] ////
|
||||
|
||||
=== conditionalPromptInference.ts ===
|
||||
declare function createPrompt<Value, Config>(
|
||||
>createPrompt : Symbol(createPrompt, Decl(conditionalPromptInference.ts, 0, 0))
|
||||
>Value : Symbol(Value, Decl(conditionalPromptInference.ts, 0, 30))
|
||||
>Config : Symbol(Config, Decl(conditionalPromptInference.ts, 0, 36))
|
||||
|
||||
view: (config: Config, done: (value: Value) => void) => void,
|
||||
>view : Symbol(view, Decl(conditionalPromptInference.ts, 0, 45))
|
||||
>config : Symbol(config, Decl(conditionalPromptInference.ts, 1, 11))
|
||||
>Config : Symbol(Config, Decl(conditionalPromptInference.ts, 0, 36))
|
||||
>done : Symbol(done, Decl(conditionalPromptInference.ts, 1, 26))
|
||||
>value : Symbol(value, Decl(conditionalPromptInference.ts, 1, 34))
|
||||
>Value : Symbol(Value, Decl(conditionalPromptInference.ts, 0, 30))
|
||||
|
||||
): (config: Config) => Value;
|
||||
>config : Symbol(config, Decl(conditionalPromptInference.ts, 2, 4))
|
||||
>Config : Symbol(Config, Decl(conditionalPromptInference.ts, 0, 36))
|
||||
>Value : Symbol(Value, Decl(conditionalPromptInference.ts, 0, 30))
|
||||
|
||||
const numberPrompt = createPrompt(<Required extends boolean>(
|
||||
>numberPrompt : Symbol(numberPrompt, Decl(conditionalPromptInference.ts, 4, 5))
|
||||
>createPrompt : Symbol(createPrompt, Decl(conditionalPromptInference.ts, 0, 0))
|
||||
>Required : Symbol(Required, Decl(conditionalPromptInference.ts, 4, 35))
|
||||
|
||||
config: { required?: Required },
|
||||
>config : Symbol(config, Decl(conditionalPromptInference.ts, 4, 61))
|
||||
>required : Symbol(required, Decl(conditionalPromptInference.ts, 5, 13))
|
||||
>Required : Symbol(Required, Decl(conditionalPromptInference.ts, 4, 35))
|
||||
|
||||
done: (value: Required extends true ? number : number | undefined) => void,
|
||||
>done : Symbol(done, Decl(conditionalPromptInference.ts, 5, 36))
|
||||
>value : Symbol(value, Decl(conditionalPromptInference.ts, 6, 11))
|
||||
>Required : Symbol(Required, Decl(conditionalPromptInference.ts, 4, 35))
|
||||
|
||||
) => {});
|
||||
|
||||
const required: number = numberPrompt<true>({ required: true });
|
||||
>required : Symbol(required, Decl(conditionalPromptInference.ts, 9, 5))
|
||||
>numberPrompt : Symbol(numberPrompt, Decl(conditionalPromptInference.ts, 4, 5))
|
||||
>required : Symbol(required, Decl(conditionalPromptInference.ts, 9, 45))
|
||||
|
||||
const optional: number | undefined = numberPrompt<false>({ required: false });
|
||||
>optional : Symbol(optional, Decl(conditionalPromptInference.ts, 10, 5))
|
||||
>numberPrompt : Symbol(numberPrompt, Decl(conditionalPromptInference.ts, 4, 5))
|
||||
>required : Symbol(required, Decl(conditionalPromptInference.ts, 10, 58))
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
//// [tests/cases/compiler/conditionalPromptInference.ts] ////
|
||||
|
||||
=== conditionalPromptInference.ts ===
|
||||
declare function createPrompt<Value, Config>(
|
||||
>createPrompt : <Value, Config>(view: (config: Config, done: (value: Value) => void) => void) => (config: Config) => Value
|
||||
|
||||
view: (config: Config, done: (value: Value) => void) => void,
|
||||
>view : (config: Config, done: (value: Value) => void) => void
|
||||
>config : Config
|
||||
>done : (value: Value) => void
|
||||
>value : Value
|
||||
|
||||
): (config: Config) => Value;
|
||||
>config : Config
|
||||
|
||||
const numberPrompt = createPrompt(<Required extends boolean>(
|
||||
>numberPrompt : <Required extends boolean>(config: { required?: Required; }) => Required extends true ? number : number | undefined
|
||||
>createPrompt(<Required extends boolean>( config: { required?: Required }, done: (value: Required extends true ? number : number | undefined) => void,) => {}) : <Required extends boolean>(config: { required?: Required; }) => Required extends true ? number : number | undefined
|
||||
>createPrompt : <Value, Config>(view: (config: Config, done: (value: Value) => void) => void) => (config: Config) => Value
|
||||
><Required extends boolean>( config: { required?: Required }, done: (value: Required extends true ? number : number | undefined) => void,) => {} : <Required extends boolean>(config: { required?: Required; }, done: (value: Required extends true ? number : number | undefined) => void) => void
|
||||
|
||||
config: { required?: Required },
|
||||
>config : { required?: Required; }
|
||||
>required : Required | undefined
|
||||
|
||||
done: (value: Required extends true ? number : number | undefined) => void,
|
||||
>done : (value: Required extends true ? number : number | undefined) => void
|
||||
>value : Required extends true ? number : number | undefined
|
||||
>true : true
|
||||
|
||||
) => {});
|
||||
|
||||
const required: number = numberPrompt<true>({ required: true });
|
||||
>required : number
|
||||
>numberPrompt<true>({ required: true }) : number
|
||||
>numberPrompt : <Required extends boolean>(config: { required?: Required; }) => Required extends true ? number : number | undefined
|
||||
>true : true
|
||||
>{ required: true } : { required: true; }
|
||||
>required : true
|
||||
>true : true
|
||||
|
||||
const optional: number | undefined = numberPrompt<false>({ required: false });
|
||||
>optional : number | undefined
|
||||
>numberPrompt<false>({ required: false }) : number | undefined
|
||||
>numberPrompt : <Required extends boolean>(config: { required?: Required; }) => Required extends true ? number : number | undefined
|
||||
>false : false
|
||||
>{ required: false } : { required: false; }
|
||||
>required : false
|
||||
>false : false
|
||||
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
//// [tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts] ////
|
||||
|
||||
=== contextualFactoryReturnToOptionalClassField.ts ===
|
||||
class Reply<T extends string | number> { value!: T; }
|
||||
>Reply : Symbol(Reply, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 12))
|
||||
>value : Symbol(Reply.value, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 40))
|
||||
>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 12))
|
||||
|
||||
declare function create<Ctor extends new () => unknown, R extends InstanceType<Ctor>>(ctor: Ctor): R;
|
||||
>create : Symbol(create, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 53))
|
||||
>Ctor : Symbol(Ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 24))
|
||||
>R : Symbol(R, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 55))
|
||||
>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --))
|
||||
>Ctor : Symbol(Ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 24))
|
||||
>ctor : Symbol(ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 86))
|
||||
>Ctor : Symbol(Ctor, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 24))
|
||||
>R : Symbol(R, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 55))
|
||||
|
||||
class Container<T extends string | number> {
|
||||
>Container : Symbol(Container, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 101))
|
||||
>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 16))
|
||||
|
||||
item?: Reply<T>;
|
||||
>item : Symbol(Container.item, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 44))
|
||||
>Reply : Symbol(Reply, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 16))
|
||||
|
||||
initialize() { this.item = create(Reply); }
|
||||
>initialize : Symbol(Container.initialize, Decl(contextualFactoryReturnToOptionalClassField.ts, 3, 20))
|
||||
>this.item : Symbol(Container.item, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 44))
|
||||
>this : Symbol(Container, Decl(contextualFactoryReturnToOptionalClassField.ts, 1, 101))
|
||||
>item : Symbol(Container.item, Decl(contextualFactoryReturnToOptionalClassField.ts, 2, 44))
|
||||
>create : Symbol(create, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 53))
|
||||
>Reply : Symbol(Reply, Decl(contextualFactoryReturnToOptionalClassField.ts, 0, 0))
|
||||
}
|
||||
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
//// [tests/cases/compiler/contextualFactoryReturnToOptionalClassField.ts] ////
|
||||
|
||||
=== contextualFactoryReturnToOptionalClassField.ts ===
|
||||
class Reply<T extends string | number> { value!: T; }
|
||||
>Reply : Reply<T>
|
||||
>value : T
|
||||
|
||||
declare function create<Ctor extends new () => unknown, R extends InstanceType<Ctor>>(ctor: Ctor): R;
|
||||
>create : <Ctor extends new () => unknown, R extends InstanceType<Ctor>>(ctor: Ctor) => R
|
||||
>ctor : Ctor
|
||||
|
||||
class Container<T extends string | number> {
|
||||
>Container : Container<T>
|
||||
|
||||
item?: Reply<T>;
|
||||
>item : Reply<T> | undefined
|
||||
|
||||
initialize() { this.item = create(Reply); }
|
||||
>initialize : () => void
|
||||
>this.item = create(Reply) : Reply<T>
|
||||
>this.item : Reply<T> | undefined
|
||||
>this : this
|
||||
>item : Reply<T> | undefined
|
||||
>create(Reply) : Reply<T>
|
||||
>create : <Ctor extends new () => unknown, R extends InstanceType<Ctor>>(ctor: Ctor) => R
|
||||
>Reply : typeof Reply
|
||||
}
|
||||
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
//// [tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts] ////
|
||||
|
||||
=== contextualGenericReturnToOptionalClassField.ts ===
|
||||
declare function lookup<T extends object = object>(): T;
|
||||
>lookup : Symbol(lookup, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 24))
|
||||
>T : Symbol(T, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 24))
|
||||
|
||||
class Container {
|
||||
>Container : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56))
|
||||
|
||||
item?: { label: string };
|
||||
>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>label : Symbol(label, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 12))
|
||||
|
||||
getLabel() {
|
||||
>getLabel : Symbol(Container.getLabel, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 29))
|
||||
|
||||
if (!this.item) this.item = lookup();
|
||||
>this.item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>this : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56))
|
||||
>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>this.item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>this : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56))
|
||||
>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>lookup : Symbol(lookup, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 0))
|
||||
|
||||
return this.item.label;
|
||||
>this.item.label : Symbol(label, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 12))
|
||||
>this.item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>this : Symbol(Container, Decl(contextualGenericReturnToOptionalClassField.ts, 0, 56))
|
||||
>item : Symbol(Container.item, Decl(contextualGenericReturnToOptionalClassField.ts, 1, 17))
|
||||
>label : Symbol(label, Decl(contextualGenericReturnToOptionalClassField.ts, 2, 12))
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
//// [tests/cases/compiler/contextualGenericReturnToOptionalClassField.ts] ////
|
||||
|
||||
=== contextualGenericReturnToOptionalClassField.ts ===
|
||||
declare function lookup<T extends object = object>(): T;
|
||||
>lookup : <T extends object = object>() => T
|
||||
|
||||
class Container {
|
||||
>Container : Container
|
||||
|
||||
item?: { label: string };
|
||||
>item : { label: string; } | undefined
|
||||
>label : string
|
||||
|
||||
getLabel() {
|
||||
>getLabel : () => string
|
||||
|
||||
if (!this.item) this.item = lookup();
|
||||
>!this.item : boolean
|
||||
>this.item : { label: string; } | undefined
|
||||
>this : this
|
||||
>item : { label: string; } | undefined
|
||||
>this.item = lookup() : { label: string; }
|
||||
>this.item : { label: string; } | undefined
|
||||
>this : this
|
||||
>item : { label: string; } | undefined
|
||||
>lookup() : { label: string; }
|
||||
>lookup : <T extends object = object>() => T
|
||||
|
||||
return this.item.label;
|
||||
>this.item.label : string
|
||||
>this.item : { label: string; }
|
||||
>this : this
|
||||
>item : { label: string; }
|
||||
>label : string
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/contextualReturnArrayPatternCallback.ts] ////
|
||||
|
||||
//// [contextualReturnArrayPatternCallback.ts]
|
||||
interface Matcher<Input, Value = unknown> {
|
||||
matcher(): { match(value: Input): boolean; value?: Value };
|
||||
}
|
||||
type Pattern<Input> = Input | Matcher<Input> | { [Key in keyof Input]?: Pattern<Input[Key]> };
|
||||
type ArrayElement<Input> = Input extends readonly (infer Value)[] ? Value : unknown;
|
||||
declare function array<Input, Value extends Pattern<ArrayElement<Input>>>(value: Value): Matcher<Input, Value>;
|
||||
declare function when<Input, Callback extends (value: Input) => unknown>(callback: Callback): Matcher<Input>;
|
||||
declare function accept<Value extends Pattern<{ list: { prop: string }[] }>>(value: Value): void;
|
||||
|
||||
accept({
|
||||
list: array({
|
||||
prop: when(value => {
|
||||
const text: string = value;
|
||||
return true;
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
//// [contextualReturnArrayPatternCallback.js]
|
||||
"use strict";
|
||||
accept({
|
||||
list: array({
|
||||
prop: when(value => {
|
||||
const text = value;
|
||||
return true;
|
||||
}),
|
||||
}),
|
||||
});
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
//// [tests/cases/compiler/contextualReturnArrayPatternCallback.ts] ////
|
||||
|
||||
=== contextualReturnArrayPatternCallback.ts ===
|
||||
interface Matcher<Input, Value = unknown> {
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 0, 18))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 0, 24))
|
||||
|
||||
matcher(): { match(value: Input): boolean; value?: Value };
|
||||
>matcher : Symbol(Matcher.matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 43))
|
||||
>match : Symbol(match, Decl(contextualReturnArrayPatternCallback.ts, 1, 16))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 1, 23))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 0, 18))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 1, 46))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 0, 24))
|
||||
}
|
||||
type Pattern<Input> = Input | Matcher<Input> | { [Key in keyof Input]?: Pattern<Input[Key]> };
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13))
|
||||
>Key : Symbol(Key, Decl(contextualReturnArrayPatternCallback.ts, 3, 50))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 3, 13))
|
||||
>Key : Symbol(Key, Decl(contextualReturnArrayPatternCallback.ts, 3, 50))
|
||||
|
||||
type ArrayElement<Input> = Input extends readonly (infer Value)[] ? Value : unknown;
|
||||
>ArrayElement : Symbol(ArrayElement, Decl(contextualReturnArrayPatternCallback.ts, 3, 94))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 4, 18))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 4, 18))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 4, 56))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 4, 56))
|
||||
|
||||
declare function array<Input, Value extends Pattern<ArrayElement<Input>>>(value: Value): Matcher<Input, Value>;
|
||||
>array : Symbol(array, Decl(contextualReturnArrayPatternCallback.ts, 4, 84))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 5, 23))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 5, 29))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1))
|
||||
>ArrayElement : Symbol(ArrayElement, Decl(contextualReturnArrayPatternCallback.ts, 3, 94))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 5, 23))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 5, 74))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 5, 29))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 5, 23))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 5, 29))
|
||||
|
||||
declare function when<Input, Callback extends (value: Input) => unknown>(callback: Callback): Matcher<Input>;
|
||||
>when : Symbol(when, Decl(contextualReturnArrayPatternCallback.ts, 5, 111))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 6, 22))
|
||||
>Callback : Symbol(Callback, Decl(contextualReturnArrayPatternCallback.ts, 6, 28))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 6, 47))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 6, 22))
|
||||
>callback : Symbol(callback, Decl(contextualReturnArrayPatternCallback.ts, 6, 73))
|
||||
>Callback : Symbol(Callback, Decl(contextualReturnArrayPatternCallback.ts, 6, 28))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnArrayPatternCallback.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnArrayPatternCallback.ts, 6, 22))
|
||||
|
||||
declare function accept<Value extends Pattern<{ list: { prop: string }[] }>>(value: Value): void;
|
||||
>accept : Symbol(accept, Decl(contextualReturnArrayPatternCallback.ts, 6, 109))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 7, 24))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnArrayPatternCallback.ts, 2, 1))
|
||||
>list : Symbol(list, Decl(contextualReturnArrayPatternCallback.ts, 7, 47))
|
||||
>prop : Symbol(prop, Decl(contextualReturnArrayPatternCallback.ts, 7, 55))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 7, 77))
|
||||
>Value : Symbol(Value, Decl(contextualReturnArrayPatternCallback.ts, 7, 24))
|
||||
|
||||
accept({
|
||||
>accept : Symbol(accept, Decl(contextualReturnArrayPatternCallback.ts, 6, 109))
|
||||
|
||||
list: array({
|
||||
>list : Symbol(list, Decl(contextualReturnArrayPatternCallback.ts, 9, 8))
|
||||
>array : Symbol(array, Decl(contextualReturnArrayPatternCallback.ts, 4, 84))
|
||||
|
||||
prop: when(value => {
|
||||
>prop : Symbol(prop, Decl(contextualReturnArrayPatternCallback.ts, 10, 17))
|
||||
>when : Symbol(when, Decl(contextualReturnArrayPatternCallback.ts, 5, 111))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 11, 19))
|
||||
|
||||
const text: string = value;
|
||||
>text : Symbol(text, Decl(contextualReturnArrayPatternCallback.ts, 12, 17))
|
||||
>value : Symbol(value, Decl(contextualReturnArrayPatternCallback.ts, 11, 19))
|
||||
|
||||
return true;
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//// [tests/cases/compiler/contextualReturnArrayPatternCallback.ts] ////
|
||||
|
||||
=== contextualReturnArrayPatternCallback.ts ===
|
||||
interface Matcher<Input, Value = unknown> {
|
||||
matcher(): { match(value: Input): boolean; value?: Value };
|
||||
>matcher : () => { match(value: Input): boolean; value?: Value; }
|
||||
>match : (value: Input) => boolean
|
||||
>value : Input
|
||||
>value : Value | undefined
|
||||
}
|
||||
type Pattern<Input> = Input | Matcher<Input> | { [Key in keyof Input]?: Pattern<Input[Key]> };
|
||||
>Pattern : Pattern<Input>
|
||||
|
||||
type ArrayElement<Input> = Input extends readonly (infer Value)[] ? Value : unknown;
|
||||
>ArrayElement : ArrayElement<Input>
|
||||
|
||||
declare function array<Input, Value extends Pattern<ArrayElement<Input>>>(value: Value): Matcher<Input, Value>;
|
||||
>array : <Input, Value extends Pattern<ArrayElement<Input>>>(value: Value) => Matcher<Input, Value>
|
||||
>value : Value
|
||||
|
||||
declare function when<Input, Callback extends (value: Input) => unknown>(callback: Callback): Matcher<Input>;
|
||||
>when : <Input, Callback extends (value: Input) => unknown>(callback: Callback) => Matcher<Input>
|
||||
>value : Input
|
||||
>callback : Callback
|
||||
|
||||
declare function accept<Value extends Pattern<{ list: { prop: string }[] }>>(value: Value): void;
|
||||
>accept : <Value extends Pattern<{ list: { prop: string; }[]; }>>(value: Value) => void
|
||||
>list : { prop: string; }[]
|
||||
>prop : string
|
||||
>value : Value
|
||||
|
||||
accept({
|
||||
>accept({ list: array({ prop: when(value => { const text: string = value; return true; }), }),}) : void
|
||||
>accept : <Value extends Pattern<{ list: { prop: string; }[]; }>>(value: Value) => void
|
||||
>{ list: array({ prop: when(value => { const text: string = value; return true; }), }),} : { list: Matcher<{ prop: string; }[], { prop: Matcher<string, unknown>; }>; }
|
||||
|
||||
list: array({
|
||||
>list : Matcher<{ prop: string; }[], { prop: Matcher<string, unknown>; }>
|
||||
>array({ prop: when(value => { const text: string = value; return true; }), }) : Matcher<{ prop: string; }[], { prop: Matcher<string, unknown>; }>
|
||||
>array : <Input, Value extends Pattern<ArrayElement<Input>>>(value: Value) => Matcher<Input, Value>
|
||||
>{ prop: when(value => { const text: string = value; return true; }), } : { prop: Matcher<string, unknown>; }
|
||||
|
||||
prop: when(value => {
|
||||
>prop : Matcher<string, unknown>
|
||||
>when(value => { const text: string = value; return true; }) : Matcher<string, unknown>
|
||||
>when : <Input, Callback extends (value: Input) => unknown>(callback: Callback) => Matcher<Input>
|
||||
>value => { const text: string = value; return true; } : (value: string) => boolean
|
||||
>value : string
|
||||
|
||||
const text: string = value;
|
||||
>text : string
|
||||
>value : string
|
||||
|
||||
return true;
|
||||
>true : true
|
||||
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//// [tests/cases/compiler/contextualReturnRecursivePatternArguments.ts] ////
|
||||
|
||||
//// [contextualReturnRecursivePatternArguments.ts]
|
||||
interface Matcher<Input, Pattern = unknown> {
|
||||
matcher(): { match(value: Input): boolean; pattern?: Pattern };
|
||||
}
|
||||
type Pattern<Input> = Input | Matcher<Input> | { [Key in keyof Input]?: Pattern<Input[Key]> };
|
||||
declare function union<Input, Patterns extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...patterns: Patterns): Matcher<Input, Patterns>;
|
||||
declare function optional<Input, Value extends unknown extends Input ? unknown : Pattern<Input>>(value: Value): Matcher<Input, Value>;
|
||||
declare function intersection<Input, Values extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...values: Values): Matcher<Input, Values>;
|
||||
declare function accept<Value extends Pattern<{ type: "a" | "b" }>>(value: Value): void;
|
||||
|
||||
accept(optional({
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
}));
|
||||
accept(intersection({
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
}));
|
||||
|
||||
|
||||
//// [contextualReturnRecursivePatternArguments.js]
|
||||
"use strict";
|
||||
accept(optional({
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
}));
|
||||
accept(intersection({
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
}));
|
||||
Vendored
+98
@@ -0,0 +1,98 @@
|
||||
//// [tests/cases/compiler/contextualReturnRecursivePatternArguments.ts] ////
|
||||
|
||||
=== contextualReturnRecursivePatternArguments.ts ===
|
||||
interface Matcher<Input, Pattern = unknown> {
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 0, 18))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 0, 24))
|
||||
|
||||
matcher(): { match(value: Input): boolean; pattern?: Pattern };
|
||||
>matcher : Symbol(Matcher.matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 45))
|
||||
>match : Symbol(match, Decl(contextualReturnRecursivePatternArguments.ts, 1, 16))
|
||||
>value : Symbol(value, Decl(contextualReturnRecursivePatternArguments.ts, 1, 23))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 0, 18))
|
||||
>pattern : Symbol(pattern, Decl(contextualReturnRecursivePatternArguments.ts, 1, 46))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 0, 24))
|
||||
}
|
||||
type Pattern<Input> = Input | Matcher<Input> | { [Key in keyof Input]?: Pattern<Input[Key]> };
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13))
|
||||
>Key : Symbol(Key, Decl(contextualReturnRecursivePatternArguments.ts, 3, 50))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 3, 13))
|
||||
>Key : Symbol(Key, Decl(contextualReturnRecursivePatternArguments.ts, 3, 50))
|
||||
|
||||
declare function union<Input, Patterns extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...patterns: Patterns): Matcher<Input, Patterns>;
|
||||
>union : Symbol(union, Decl(contextualReturnRecursivePatternArguments.ts, 3, 94))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23))
|
||||
>Patterns : Symbol(Patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 29))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23))
|
||||
>patterns : Symbol(patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 95))
|
||||
>Patterns : Symbol(Patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 29))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 4, 23))
|
||||
>Patterns : Symbol(Patterns, Decl(contextualReturnRecursivePatternArguments.ts, 4, 29))
|
||||
|
||||
declare function optional<Input, Value extends unknown extends Input ? unknown : Pattern<Input>>(value: Value): Matcher<Input, Value>;
|
||||
>optional : Symbol(optional, Decl(contextualReturnRecursivePatternArguments.ts, 4, 144))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26))
|
||||
>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 32))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26))
|
||||
>value : Symbol(value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 97))
|
||||
>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 32))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 5, 26))
|
||||
>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 5, 32))
|
||||
|
||||
declare function intersection<Input, Values extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...values: Values): Matcher<Input, Values>;
|
||||
>intersection : Symbol(intersection, Decl(contextualReturnRecursivePatternArguments.ts, 5, 134))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30))
|
||||
>Values : Symbol(Values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 36))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30))
|
||||
>values : Symbol(values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 100))
|
||||
>Values : Symbol(Values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 36))
|
||||
>Matcher : Symbol(Matcher, Decl(contextualReturnRecursivePatternArguments.ts, 0, 0))
|
||||
>Input : Symbol(Input, Decl(contextualReturnRecursivePatternArguments.ts, 6, 30))
|
||||
>Values : Symbol(Values, Decl(contextualReturnRecursivePatternArguments.ts, 6, 36))
|
||||
|
||||
declare function accept<Value extends Pattern<{ type: "a" | "b" }>>(value: Value): void;
|
||||
>accept : Symbol(accept, Decl(contextualReturnRecursivePatternArguments.ts, 6, 143))
|
||||
>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 7, 24))
|
||||
>Pattern : Symbol(Pattern, Decl(contextualReturnRecursivePatternArguments.ts, 2, 1))
|
||||
>type : Symbol(type, Decl(contextualReturnRecursivePatternArguments.ts, 7, 47))
|
||||
>value : Symbol(value, Decl(contextualReturnRecursivePatternArguments.ts, 7, 68))
|
||||
>Value : Symbol(Value, Decl(contextualReturnRecursivePatternArguments.ts, 7, 24))
|
||||
|
||||
accept(optional({
|
||||
>accept : Symbol(accept, Decl(contextualReturnRecursivePatternArguments.ts, 6, 143))
|
||||
>optional : Symbol(optional, Decl(contextualReturnRecursivePatternArguments.ts, 4, 144))
|
||||
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
>type : Symbol(type, Decl(contextualReturnRecursivePatternArguments.ts, 9, 17))
|
||||
>union : Symbol(union, Decl(contextualReturnRecursivePatternArguments.ts, 3, 94))
|
||||
|
||||
}));
|
||||
accept(intersection({
|
||||
>accept : Symbol(accept, Decl(contextualReturnRecursivePatternArguments.ts, 6, 143))
|
||||
>intersection : Symbol(intersection, Decl(contextualReturnRecursivePatternArguments.ts, 5, 134))
|
||||
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
>type : Symbol(type, Decl(contextualReturnRecursivePatternArguments.ts, 13, 21))
|
||||
>union : Symbol(union, Decl(contextualReturnRecursivePatternArguments.ts, 3, 94))
|
||||
|
||||
}));
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
//// [tests/cases/compiler/contextualReturnRecursivePatternArguments.ts] ////
|
||||
|
||||
=== contextualReturnRecursivePatternArguments.ts ===
|
||||
interface Matcher<Input, Pattern = unknown> {
|
||||
matcher(): { match(value: Input): boolean; pattern?: Pattern };
|
||||
>matcher : () => { match(value: Input): boolean; pattern?: Pattern; }
|
||||
>match : (value: Input) => boolean
|
||||
>value : Input
|
||||
>pattern : Pattern | undefined
|
||||
}
|
||||
type Pattern<Input> = Input | Matcher<Input> | { [Key in keyof Input]?: Pattern<Input[Key]> };
|
||||
>Pattern : Pattern<Input>
|
||||
|
||||
declare function union<Input, Patterns extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...patterns: Patterns): Matcher<Input, Patterns>;
|
||||
>union : <Input, Patterns extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...patterns: Patterns) => Matcher<Input, Patterns>
|
||||
>patterns : Patterns
|
||||
|
||||
declare function optional<Input, Value extends unknown extends Input ? unknown : Pattern<Input>>(value: Value): Matcher<Input, Value>;
|
||||
>optional : <Input, Value extends unknown extends Input ? unknown : Pattern<Input>>(value: Value) => Matcher<Input, Value>
|
||||
>value : Value
|
||||
|
||||
declare function intersection<Input, Values extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...values: Values): Matcher<Input, Values>;
|
||||
>intersection : <Input, Values extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...values: Values) => Matcher<Input, Values>
|
||||
>values : Values
|
||||
|
||||
declare function accept<Value extends Pattern<{ type: "a" | "b" }>>(value: Value): void;
|
||||
>accept : <Value extends Pattern<{ type: "a" | "b"; }>>(value: Value) => void
|
||||
>type : "a" | "b"
|
||||
>value : Value
|
||||
|
||||
accept(optional({
|
||||
>accept(optional({ // @ts-expect-error type: union("oops"),})) : void
|
||||
>accept : <Value extends Pattern<{ type: "a" | "b"; }>>(value: Value) => void
|
||||
>optional({ // @ts-expect-error type: union("oops"),}) : Matcher<unknown, { type: Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>; }>
|
||||
>optional : <Input, Value extends unknown extends Input ? unknown : Pattern<Input>>(value: Value) => Matcher<Input, Value>
|
||||
>{ // @ts-expect-error type: union("oops"),} : { type: Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>; }
|
||||
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
>type : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>
|
||||
>union("oops") : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>
|
||||
>union : <Input, Patterns extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...patterns: Patterns) => Matcher<Input, Patterns>
|
||||
>"oops" : "oops"
|
||||
|
||||
}));
|
||||
accept(intersection({
|
||||
>accept(intersection({ // @ts-expect-error type: union("oops"),})) : void
|
||||
>accept : <Value extends Pattern<{ type: "a" | "b"; }>>(value: Value) => void
|
||||
>intersection({ // @ts-expect-error type: union("oops"),}) : Matcher<unknown, [{ type: Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>; }]>
|
||||
>intersection : <Input, Values extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...values: Values) => Matcher<Input, Values>
|
||||
>{ // @ts-expect-error type: union("oops"),} : { type: Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>; }
|
||||
|
||||
// @ts-expect-error
|
||||
type: union("oops"),
|
||||
>type : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>
|
||||
>union("oops") : Matcher<"a" | "b", readonly [Pattern<"a" | "b">, ...Pattern<"a" | "b">[]]>
|
||||
>union : <Input, Patterns extends readonly [Pattern<Input>, ...Pattern<Input>[]]>(...patterns: Patterns) => Matcher<Input, Patterns>
|
||||
>"oops" : "oops"
|
||||
|
||||
}));
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//// [tests/cases/compiler/contextualReturnSpreadPickInference.ts] ////
|
||||
|
||||
=== contextualReturnSpreadPickInference.ts ===
|
||||
type Many<T> = T | readonly T[];
|
||||
>Many : Symbol(Many, Decl(contextualReturnSpreadPickInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 0, 10))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 0, 10))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 0, 10))
|
||||
|
||||
declare function pick<T extends object, Key extends keyof T>(
|
||||
>pick : Symbol(pick, Decl(contextualReturnSpreadPickInference.ts, 0, 32))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22))
|
||||
>Key : Symbol(Key, Decl(contextualReturnSpreadPickInference.ts, 1, 39))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22))
|
||||
|
||||
object: T,
|
||||
>object : Symbol(object, Decl(contextualReturnSpreadPickInference.ts, 1, 61))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22))
|
||||
|
||||
...props: Many<Key>[]
|
||||
>props : Symbol(props, Decl(contextualReturnSpreadPickInference.ts, 2, 14))
|
||||
>Many : Symbol(Many, Decl(contextualReturnSpreadPickInference.ts, 0, 0))
|
||||
>Key : Symbol(Key, Decl(contextualReturnSpreadPickInference.ts, 1, 39))
|
||||
|
||||
): Pick<T, Key>;
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>T : Symbol(T, Decl(contextualReturnSpreadPickInference.ts, 1, 22))
|
||||
>Key : Symbol(Key, Decl(contextualReturnSpreadPickInference.ts, 1, 39))
|
||||
|
||||
async function getPage(page: any): Promise<{ title: string; intro: string }> {
|
||||
>getPage : Symbol(getPage, Decl(contextualReturnSpreadPickInference.ts, 4, 16))
|
||||
>page : Symbol(page, Decl(contextualReturnSpreadPickInference.ts, 6, 23))
|
||||
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>title : Symbol(title, Decl(contextualReturnSpreadPickInference.ts, 6, 44))
|
||||
>intro : Symbol(intro, Decl(contextualReturnSpreadPickInference.ts, 6, 59))
|
||||
|
||||
return {
|
||||
title: "",
|
||||
>title : Symbol(title, Decl(contextualReturnSpreadPickInference.ts, 7, 12))
|
||||
|
||||
...pick(page, ["intro"]),
|
||||
>pick : Symbol(pick, Decl(contextualReturnSpreadPickInference.ts, 0, 32))
|
||||
>page : Symbol(page, Decl(contextualReturnSpreadPickInference.ts, 6, 23))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//// [tests/cases/compiler/contextualReturnSpreadPickInference.ts] ////
|
||||
|
||||
=== contextualReturnSpreadPickInference.ts ===
|
||||
type Many<T> = T | readonly T[];
|
||||
>Many : Many<T>
|
||||
|
||||
declare function pick<T extends object, Key extends keyof T>(
|
||||
>pick : <T extends object, Key extends keyof T>(object: T, ...props: Many<Key>[]) => Pick<T, Key>
|
||||
|
||||
object: T,
|
||||
>object : T
|
||||
|
||||
...props: Many<Key>[]
|
||||
>props : Many<Key>[]
|
||||
|
||||
): Pick<T, Key>;
|
||||
|
||||
async function getPage(page: any): Promise<{ title: string; intro: string }> {
|
||||
>getPage : (page: any) => Promise<{ title: string; intro: string; }>
|
||||
>page : any
|
||||
>title : string
|
||||
>intro : string
|
||||
|
||||
return {
|
||||
>{ title: "", ...pick(page, ["intro"]), } : { title: string; intro: any; }
|
||||
|
||||
title: "",
|
||||
>title : string
|
||||
>"" : ""
|
||||
|
||||
...pick(page, ["intro"]),
|
||||
>pick(page, ["intro"]) : Pick<any, "intro">
|
||||
>pick : <T extends object, Key extends keyof T>(object: T, ...props: Many<Key>[]) => Pick<T, Key>
|
||||
>page : any
|
||||
>["intro"] : "intro"[]
|
||||
>"intro" : "intro"
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//// [tests/cases/compiler/contextualRuleMessageInference.ts] ////
|
||||
|
||||
=== contextualRuleMessageInference.ts ===
|
||||
type DeferredInference<T> = [T][T extends unknown ? 0 : never];
|
||||
>DeferredInference : Symbol(DeferredInference, Decl(contextualRuleMessageInference.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(contextualRuleMessageInference.ts, 0, 23))
|
||||
>T : Symbol(T, Decl(contextualRuleMessageInference.ts, 0, 23))
|
||||
>T : Symbol(T, Decl(contextualRuleMessageInference.ts, 0, 23))
|
||||
|
||||
declare function runRule<Message extends string>(
|
||||
>runRule : Symbol(runRule, Decl(contextualRuleMessageInference.ts, 0, 63))
|
||||
>Message : Symbol(Message, Decl(contextualRuleMessageInference.ts, 2, 25))
|
||||
|
||||
rule: Message,
|
||||
>rule : Symbol(rule, Decl(contextualRuleMessageInference.ts, 2, 49))
|
||||
>Message : Symbol(Message, Decl(contextualRuleMessageInference.ts, 2, 25))
|
||||
|
||||
tests: { invalid: readonly { errors: readonly { messageId: DeferredInference<Message> }[] }[] },
|
||||
>tests : Symbol(tests, Decl(contextualRuleMessageInference.ts, 3, 18))
|
||||
>invalid : Symbol(invalid, Decl(contextualRuleMessageInference.ts, 4, 12))
|
||||
>errors : Symbol(errors, Decl(contextualRuleMessageInference.ts, 4, 32))
|
||||
>messageId : Symbol(messageId, Decl(contextualRuleMessageInference.ts, 4, 51))
|
||||
>DeferredInference : Symbol(DeferredInference, Decl(contextualRuleMessageInference.ts, 0, 0))
|
||||
>Message : Symbol(Message, Decl(contextualRuleMessageInference.ts, 2, 25))
|
||||
|
||||
): void;
|
||||
|
||||
runRule("forbiddenAct", {
|
||||
>runRule : Symbol(runRule, Decl(contextualRuleMessageInference.ts, 0, 63))
|
||||
|
||||
invalid: ["act()"].map(() => ({
|
||||
>invalid : Symbol(invalid, Decl(contextualRuleMessageInference.ts, 7, 25))
|
||||
>["act()"].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
errors: [{ messageId: "forbiddenAct" }],
|
||||
>errors : Symbol(errors, Decl(contextualRuleMessageInference.ts, 8, 35))
|
||||
>messageId : Symbol(messageId, Decl(contextualRuleMessageInference.ts, 9, 18))
|
||||
|
||||
})),
|
||||
});
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
//// [tests/cases/compiler/contextualRuleMessageInference.ts] ////
|
||||
|
||||
=== contextualRuleMessageInference.ts ===
|
||||
type DeferredInference<T> = [T][T extends unknown ? 0 : never];
|
||||
>DeferredInference : DeferredInference<T>
|
||||
|
||||
declare function runRule<Message extends string>(
|
||||
>runRule : <Message extends string>(rule: Message, tests: { invalid: readonly { errors: readonly { messageId: DeferredInference<Message>; }[]; }[]; }) => void
|
||||
|
||||
rule: Message,
|
||||
>rule : Message
|
||||
|
||||
tests: { invalid: readonly { errors: readonly { messageId: DeferredInference<Message> }[] }[] },
|
||||
>tests : { invalid: readonly { errors: readonly { messageId: DeferredInference<Message>; }[]; }[]; }
|
||||
>invalid : readonly { errors: readonly { messageId: DeferredInference<Message>; }[]; }[]
|
||||
>errors : readonly { messageId: DeferredInference<Message>; }[]
|
||||
>messageId : DeferredInference<Message>
|
||||
|
||||
): void;
|
||||
|
||||
runRule("forbiddenAct", {
|
||||
>runRule("forbiddenAct", { invalid: ["act()"].map(() => ({ errors: [{ messageId: "forbiddenAct" }], })),}) : void
|
||||
>runRule : <Message extends string>(rule: Message, tests: { invalid: readonly { errors: readonly { messageId: DeferredInference<Message>; }[]; }[]; }) => void
|
||||
>"forbiddenAct" : "forbiddenAct"
|
||||
>{ invalid: ["act()"].map(() => ({ errors: [{ messageId: "forbiddenAct" }], })),} : { invalid: { errors: { messageId: "forbiddenAct"; }[]; }[]; }
|
||||
|
||||
invalid: ["act()"].map(() => ({
|
||||
>invalid : { errors: { messageId: "forbiddenAct"; }[]; }[]
|
||||
>["act()"].map(() => ({ errors: [{ messageId: "forbiddenAct" }], })) : { errors: { messageId: "forbiddenAct"; }[]; }[]
|
||||
>["act()"].map : <U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]
|
||||
>["act()"] : string[]
|
||||
>"act()" : "act()"
|
||||
>map : <U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]
|
||||
>() => ({ errors: [{ messageId: "forbiddenAct" }], }) : () => { errors: { messageId: "forbiddenAct"; }[]; }
|
||||
>({ errors: [{ messageId: "forbiddenAct" }], }) : { errors: { messageId: "forbiddenAct"; }[]; }
|
||||
>{ errors: [{ messageId: "forbiddenAct" }], } : { errors: { messageId: "forbiddenAct"; }[]; }
|
||||
|
||||
errors: [{ messageId: "forbiddenAct" }],
|
||||
>errors : { messageId: "forbiddenAct"; }[]
|
||||
>[{ messageId: "forbiddenAct" }] : { messageId: "forbiddenAct"; }[]
|
||||
>{ messageId: "forbiddenAct" } : { messageId: "forbiddenAct"; }
|
||||
>messageId : "forbiddenAct"
|
||||
>"forbiddenAct" : "forbiddenAct"
|
||||
|
||||
})),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [tests/cases/compiler/correlatedLabelNullishFallback.ts] ////
|
||||
|
||||
//// [correlatedLabelNullishFallback.ts]
|
||||
function label(options: { label: string; alias: string } | { label: object; alias?: string }) {
|
||||
if (typeof options.label === "string") return options.alias ?? options.label;
|
||||
}
|
||||
|
||||
|
||||
//// [correlatedLabelNullishFallback.js]
|
||||
"use strict";
|
||||
function label(options) {
|
||||
if (typeof options.label === "string")
|
||||
return options.alias ?? options.label;
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
//// [tests/cases/compiler/correlatedLabelNullishFallback.ts] ////
|
||||
|
||||
=== correlatedLabelNullishFallback.ts ===
|
||||
function label(options: { label: string; alias: string } | { label: object; alias?: string }) {
|
||||
>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 0))
|
||||
>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15))
|
||||
>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25))
|
||||
>alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 40))
|
||||
>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 60))
|
||||
>alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 75))
|
||||
|
||||
if (typeof options.label === "string") return options.alias ?? options.label;
|
||||
>options.label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60))
|
||||
>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15))
|
||||
>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60))
|
||||
>options.alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 40), Decl(correlatedLabelNullishFallback.ts, 0, 75))
|
||||
>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15))
|
||||
>alias : Symbol(alias, Decl(correlatedLabelNullishFallback.ts, 0, 40), Decl(correlatedLabelNullishFallback.ts, 0, 75))
|
||||
>options.label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60))
|
||||
>options : Symbol(options, Decl(correlatedLabelNullishFallback.ts, 0, 15))
|
||||
>label : Symbol(label, Decl(correlatedLabelNullishFallback.ts, 0, 25), Decl(correlatedLabelNullishFallback.ts, 0, 60))
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
//// [tests/cases/compiler/correlatedLabelNullishFallback.ts] ////
|
||||
|
||||
=== correlatedLabelNullishFallback.ts ===
|
||||
function label(options: { label: string; alias: string } | { label: object; alias?: string }) {
|
||||
>label : (options: { label: string; alias: string; } | { label: object; alias?: string; }) => string | undefined
|
||||
>options : { label: string; alias: string; } | { label: object; alias?: string; }
|
||||
>label : string
|
||||
>alias : string
|
||||
>label : object
|
||||
>alias : string | undefined
|
||||
|
||||
if (typeof options.label === "string") return options.alias ?? options.label;
|
||||
>typeof options.label === "string" : boolean
|
||||
>typeof options.label : "bigint" | "boolean" | "function" | "number" | "object" | "string" | "symbol" | "undefined"
|
||||
>options.label : string | object
|
||||
>options : { label: string; alias: string; } | { label: object; alias?: string; }
|
||||
>label : string | object
|
||||
>"string" : "string"
|
||||
>options.alias ?? options.label : string
|
||||
>options.alias : string | undefined
|
||||
>options : { label: string; alias: string; } | { label: object; alias?: string; }
|
||||
>alias : string | undefined
|
||||
>options.label : string
|
||||
>options : { label: string; alias: string; } | { label: object; alias?: string; }
|
||||
>label : string
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/cssStyleDeclarationCompatibility.ts] ////
|
||||
|
||||
=== cssStyleDeclarationCompatibility.ts ===
|
||||
declare const element: HTMLElement;
|
||||
>element : Symbol(element, Decl(cssStyleDeclarationCompatibility.ts, 0, 13))
|
||||
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
const style: CSSStyleDeclaration = element.style;
|
||||
>style : Symbol(style, Decl(cssStyleDeclarationCompatibility.ts, 1, 5))
|
||||
>CSSStyleDeclaration : Symbol(CSSStyleDeclaration, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>element.style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>element : Symbol(element, Decl(cssStyleDeclarationCompatibility.ts, 0, 13))
|
||||
>style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
[...element.style];
|
||||
>element.style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
>element : Symbol(element, Decl(cssStyleDeclarationCompatibility.ts, 0, 13))
|
||||
>style : Symbol(ElementCSSInlineStyle.style, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
//// [tests/cases/compiler/cssStyleDeclarationCompatibility.ts] ////
|
||||
|
||||
=== cssStyleDeclarationCompatibility.ts ===
|
||||
declare const element: HTMLElement;
|
||||
>element : HTMLElement
|
||||
|
||||
const style: CSSStyleDeclaration = element.style;
|
||||
>style : CSSStyleDeclaration
|
||||
>element.style : CSSStyleDeclaration
|
||||
>element : HTMLElement
|
||||
>style : CSSStyleDeclaration
|
||||
|
||||
[...element.style];
|
||||
>[...element.style] : string[]
|
||||
>...element.style : string
|
||||
>element.style : CSSStyleDeclaration
|
||||
>element : HTMLElement
|
||||
>style : CSSStyleDeclaration
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
//// [tests/cases/compiler/declarationDefaultImportSuggestion.ts] ////
|
||||
|
||||
=== store.d.ts ===
|
||||
export interface Store {}
|
||||
>Store : Symbol(Store, Decl(store.d.ts, 0, 0))
|
||||
|
||||
=== main.ts ===
|
||||
import Store from "./store";
|
||||
>Store : Symbol(Store, Decl(main.ts, 0, 6))
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
//// [tests/cases/compiler/declarationDefaultImportSuggestion.ts] ////
|
||||
|
||||
=== store.d.ts ===
|
||||
|
||||
export interface Store {}
|
||||
|
||||
=== main.ts ===
|
||||
import Store from "./store";
|
||||
>Store : typeof Store
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files.
|
||||
The file is in the program because:
|
||||
Part of 'files' list in tsconfig.json
|
||||
/project/example/tsconfig.json(3,9): error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
|
||||
Visit https://aka.ms/ts6 for migration information.
|
||||
|
||||
|
||||
!!! error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files.
|
||||
!!! error TS6059: The file is in the program because:
|
||||
!!! error TS6059: Part of 'files' list in tsconfig.json
|
||||
!!! related TS1410 /project/example/tsconfig.json:5:15: File is matched by 'files' list specified here.
|
||||
==== /project/example/tsconfig.json (1 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "."
|
||||
~~~~~~~~
|
||||
!!! error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
|
||||
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
|
||||
},
|
||||
"files": ["../src/index.ts"]
|
||||
}
|
||||
|
||||
==== /project/src/index.ts (0 errors) ====
|
||||
export const value = 0;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
//// [tests/cases/compiler/defaultRootDirExternalFiles.ts] ////
|
||||
|
||||
//// [index.ts]
|
||||
export const value = 0;
|
||||
|
||||
|
||||
//// [index.js]
|
||||
export const value = 0;
|
||||
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultRootDirExternalFiles.ts] ////
|
||||
|
||||
=== /project/src/index.ts ===
|
||||
export const value = 0;
|
||||
>value : Symbol(value, Decl(index.ts, 0, 12))
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
//// [tests/cases/compiler/defaultRootDirExternalFiles.ts] ////
|
||||
|
||||
=== /project/src/index.ts ===
|
||||
export const value = 0;
|
||||
>value : 0
|
||||
>0 : 0
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
|
||||
Visit https://aka.ms/ts6 for migration information.
|
||||
error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files.
|
||||
The file is in the program because:
|
||||
Matched by include pattern '../src' in '/project/example/tsconfig.json'
|
||||
|
||||
|
||||
!!! error TS5011: The common source directory of 'tsconfig.json' is '../src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
|
||||
!!! error TS5011: Visit https://aka.ms/ts6 for migration information.
|
||||
!!! error TS6059: File '/project/src/index.ts' is not under 'rootDir' '/project/example'. 'rootDir' is expected to contain all source files.
|
||||
!!! error TS6059: The file is in the program because:
|
||||
!!! error TS6059: Matched by include pattern '../src' in '/project/example/tsconfig.json'
|
||||
==== /project/example/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"extends": "../tsconfig.json"
|
||||
}
|
||||
|
||||
==== /project/src/index.ts (0 errors) ====
|
||||
export const value = 0;
|
||||
|
||||
==== /project/tsconfig.json (0 errors) ====
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/defaultRootDirInheritedInclude.ts] ////
|
||||
|
||||
//// [tsconfig.json]
|
||||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "lib"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
//// [index.ts]
|
||||
export const value = 0;
|
||||
|
||||
|
||||
//// [index.js]
|
||||
export const value = 0;
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultRootDirInheritedInclude.ts] ////
|
||||
|
||||
=== /project/src/index.ts ===
|
||||
export const value = 0;
|
||||
>value : Symbol(value, Decl(index.ts, 0, 12))
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
//// [tests/cases/compiler/defaultRootDirInheritedInclude.ts] ////
|
||||
|
||||
=== /project/src/index.ts ===
|
||||
export const value = 0;
|
||||
>value : 0
|
||||
>0 : 0
|
||||
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
/main.mts(1,23): error TS2307: Cannot find module 'engine' or its corresponding type declarations.
|
||||
/main.mts(2,35): error TS2307: Cannot find module 'engine' or its corresponding type declarations.
|
||||
|
||||
|
||||
==== /main.mts (2 errors) ====
|
||||
import { value } from "engine";
|
||||
~~~~~~~~
|
||||
!!! error TS2307: Cannot find module 'engine' or its corresponding type declarations.
|
||||
export { default as engine } from "engine";
|
||||
~~~~~~~~
|
||||
!!! error TS2307: Cannot find module 'engine' or its corresponding type declarations.
|
||||
|
||||
==== /node_modules/@types/runtime/index.d.ts (0 errors) ====
|
||||
declare module "engine" {
|
||||
export const value: number;
|
||||
export default function read(): void;
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts] ////
|
||||
|
||||
=== /main.mts ===
|
||||
import { value } from "engine";
|
||||
>value : Symbol(value, Decl(main.mts, 0, 8))
|
||||
|
||||
export { default as engine } from "engine";
|
||||
>engine : Symbol(engine, Decl(main.mts, 1, 8))
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeAmbientModuleImports.ts] ////
|
||||
|
||||
=== /main.mts ===
|
||||
import { value } from "engine";
|
||||
>value : any
|
||||
|
||||
export { default as engine } from "engine";
|
||||
>default : any
|
||||
>engine : any
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/main.ts(1,1): error TS2304: Cannot find name '__dirname'.
|
||||
|
||||
|
||||
==== /main.ts (1 errors) ====
|
||||
__dirname;
|
||||
~~~~~~~~~
|
||||
!!! error TS2304: Cannot find name '__dirname'.
|
||||
|
||||
==== /node_modules/@types/runtime/index.d.ts (0 errors) ====
|
||||
declare const __dirname: string;
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts] ////
|
||||
|
||||
=== /main.ts ===
|
||||
|
||||
__dirname;
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeAmbientPackages.ts] ////
|
||||
|
||||
=== /main.ts ===
|
||||
__dirname;
|
||||
>__dirname : any
|
||||
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
error TS2318: Cannot find global type 'Boolean'.
|
||||
error TS2318: Cannot find global type 'CallableFunction'.
|
||||
error TS2318: Cannot find global type 'IArguments'.
|
||||
error TS2318: Cannot find global type 'NewableFunction'.
|
||||
error TS2318: Cannot find global type 'Number'.
|
||||
error TS2318: Cannot find global type 'Object'.
|
||||
|
||||
|
||||
!!! error TS2318: Cannot find global type 'Boolean'.
|
||||
!!! error TS2318: Cannot find global type 'CallableFunction'.
|
||||
!!! error TS2318: Cannot find global type 'IArguments'.
|
||||
!!! error TS2318: Cannot find global type 'NewableFunction'.
|
||||
!!! error TS2318: Cannot find global type 'Number'.
|
||||
!!! error TS2318: Cannot find global type 'Object'.
|
||||
==== /main.ts (0 errors) ====
|
||||
export {};
|
||||
|
||||
==== /node_modules/@types/runtime/index.d.ts (0 errors) ====
|
||||
/// <reference lib="es2020" />
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts] ////
|
||||
|
||||
=== /main.ts ===
|
||||
|
||||
export {};
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeBaseLibraryReferences.ts] ////
|
||||
|
||||
=== /main.ts ===
|
||||
|
||||
export {};
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/main.ts(1,18): error TS2550: Property 'includes' does not exist on type 'string[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2016' or later.
|
||||
|
||||
|
||||
==== /main.ts (1 errors) ====
|
||||
["workflow.yml"].includes("workflow.yml");
|
||||
~~~~~~~~
|
||||
!!! error TS2550: Property 'includes' does not exist on type 'string[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2016' or later.
|
||||
|
||||
==== /node_modules/@types/runtime/index.d.ts (0 errors) ====
|
||||
/// <reference lib="es2018" />
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts] ////
|
||||
|
||||
=== /main.ts ===
|
||||
|
||||
["workflow.yml"].includes("workflow.yml");
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
//// [tests/cases/compiler/defaultTypesExcludeLibraryReferences.ts] ////
|
||||
|
||||
=== /main.ts ===
|
||||
["workflow.yml"].includes("workflow.yml");
|
||||
>["workflow.yml"].includes("workflow.yml") : any
|
||||
>["workflow.yml"].includes : any
|
||||
>["workflow.yml"] : string[]
|
||||
>"workflow.yml" : "workflow.yml"
|
||||
>includes : any
|
||||
>"workflow.yml" : "workflow.yml"
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
//// [tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts] ////
|
||||
|
||||
//// [defaultWeakMapInferredPropertyAssignment.ts]
|
||||
const frameInfo = { frames: new WeakMap() };
|
||||
const target: { frames: WeakMap<{ id: string }, number> } = frameInfo;
|
||||
|
||||
|
||||
//// [defaultWeakMapInferredPropertyAssignment.js]
|
||||
"use strict";
|
||||
const frameInfo = { frames: new WeakMap() };
|
||||
const target = frameInfo;
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
//// [tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts] ////
|
||||
|
||||
=== defaultWeakMapInferredPropertyAssignment.ts ===
|
||||
const frameInfo = { frames: new WeakMap() };
|
||||
>frameInfo : Symbol(frameInfo, Decl(defaultWeakMapInferredPropertyAssignment.ts, 0, 5))
|
||||
>frames : Symbol(frames, Decl(defaultWeakMapInferredPropertyAssignment.ts, 0, 19))
|
||||
>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
|
||||
const target: { frames: WeakMap<{ id: string }, number> } = frameInfo;
|
||||
>target : Symbol(target, Decl(defaultWeakMapInferredPropertyAssignment.ts, 1, 5))
|
||||
>frames : Symbol(frames, Decl(defaultWeakMapInferredPropertyAssignment.ts, 1, 15))
|
||||
>WeakMap : Symbol(WeakMap, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
|
||||
>id : Symbol(id, Decl(defaultWeakMapInferredPropertyAssignment.ts, 1, 33))
|
||||
>frameInfo : Symbol(frameInfo, Decl(defaultWeakMapInferredPropertyAssignment.ts, 0, 5))
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
//// [tests/cases/compiler/defaultWeakMapInferredPropertyAssignment.ts] ////
|
||||
|
||||
=== defaultWeakMapInferredPropertyAssignment.ts ===
|
||||
const frameInfo = { frames: new WeakMap() };
|
||||
>frameInfo : { frames: WeakMap<WeakKey, any>; }
|
||||
>{ frames: new WeakMap() } : { frames: WeakMap<WeakKey, any>; }
|
||||
>frames : WeakMap<WeakKey, any>
|
||||
>new WeakMap() : WeakMap<WeakKey, any>
|
||||
>WeakMap : WeakMapConstructor
|
||||
|
||||
const target: { frames: WeakMap<{ id: string }, number> } = frameInfo;
|
||||
>target : { frames: WeakMap<{ id: string; }, number>; }
|
||||
>frames : WeakMap<{ id: string; }, number>
|
||||
>id : string
|
||||
>frameInfo : { frames: WeakMap<WeakKey, any>; }
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
distributedRecursiveMappedType.ts(2,49): error TS2344: Type 'Input[Key]' does not satisfy the constraint 'Shape[Key]'.
|
||||
Type 'Input' is not assignable to type 'Shape'.
|
||||
'Input' is only assignable to the non-distributed 'Shape', but 'Shape' has been distributed here.
|
||||
distributedRecursiveMappedType.ts(2,49): error TS2536: Type 'Key' cannot be used to index type 'Input'.
|
||||
|
||||
|
||||
==== distributedRecursiveMappedType.ts (2 errors) ====
|
||||
type Exact<Shape, Input extends Shape> = Shape extends Shape
|
||||
? { [Key in keyof Shape]: Exact<Shape[Key], Input[Key]> }
|
||||
~~~~~~~~~~
|
||||
!!! error TS2344: Type 'Input[Key]' does not satisfy the constraint 'Shape[Key]'.
|
||||
!!! error TS2344: Type 'Input' is not assignable to type 'Shape'.
|
||||
!!! error TS2344: 'Input' is only assignable to the non-distributed 'Shape', but 'Shape' has been distributed here.
|
||||
~~~~~~~~~~
|
||||
!!! error TS2536: Type 'Key' cannot be used to index type 'Input'.
|
||||
: never;
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
//// [tests/cases/compiler/distributedRecursiveMappedType.ts] ////
|
||||
|
||||
=== distributedRecursiveMappedType.ts ===
|
||||
type Exact<Shape, Input extends Shape> = Shape extends Shape
|
||||
>Exact : Symbol(Exact, Decl(distributedRecursiveMappedType.ts, 0, 0))
|
||||
>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11))
|
||||
>Input : Symbol(Input, Decl(distributedRecursiveMappedType.ts, 0, 17))
|
||||
>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11))
|
||||
>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11))
|
||||
>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11))
|
||||
|
||||
? { [Key in keyof Shape]: Exact<Shape[Key], Input[Key]> }
|
||||
>Key : Symbol(Key, Decl(distributedRecursiveMappedType.ts, 1, 9))
|
||||
>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11))
|
||||
>Exact : Symbol(Exact, Decl(distributedRecursiveMappedType.ts, 0, 0))
|
||||
>Shape : Symbol(Shape, Decl(distributedRecursiveMappedType.ts, 0, 11))
|
||||
>Key : Symbol(Key, Decl(distributedRecursiveMappedType.ts, 1, 9))
|
||||
>Input : Symbol(Input, Decl(distributedRecursiveMappedType.ts, 0, 17))
|
||||
>Key : Symbol(Key, Decl(distributedRecursiveMappedType.ts, 1, 9))
|
||||
|
||||
: never;
|
||||
|
||||
Loaded 100 of 479 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user