Skip to content

Commit

Permalink
feat(repl): allow using "type" command on types/interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
ejose19 committed Jul 18, 2021
1 parent e865076 commit 6f7b2ff
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/index.ts
Expand Up @@ -348,6 +348,7 @@ export interface TsConfigOptions
export interface TypeInfo {
name: string;
comment: string;
kind?: _ts.ScriptElementKind;
}

/**
Expand Down Expand Up @@ -831,8 +832,9 @@ export function create(rawOptions: CreateOptions = {}): Service {
const info = service.getQuickInfoAtPosition(fileName, position);
const name = ts.displayPartsToString(info ? info.displayParts : []);
const comment = ts.displayPartsToString(info ? info.documentation : []);
const kind = info?.kind;

return { name, comment };
return { name, comment, kind };
};
} else {
const sys: _ts.System & _ts.FormatDiagnosticsHost = {
Expand Down
26 changes: 25 additions & 1 deletion src/repl.ts
Expand Up @@ -8,6 +8,7 @@ import { readFileSync, statSync } from 'fs';
import { Console } from 'console';
import type * as tty from 'tty';
import Module = require('module');
import { ScriptElementKind } from 'typescript';

/** @internal */
export const EVAL_FILENAME = `[eval].ts`;
Expand Down Expand Up @@ -306,14 +307,37 @@ function startRepl(
}

const undo = appendEval(state, identifier);
const { name, comment } = service.getTypeInfo(
let { name, comment, kind } = service.getTypeInfo(
state.input,
state.path,
state.input.length
);

undo();

// Check if the user intended to query a Type/Interface
if (kind === '') {
// Workaround to get type information
const undo = appendEval(state, `1 as ${identifier}`);
const getTypeInfoRes = service.getTypeInfo(
state.input,
state.path,
state.input.length
);

undo();

if (
[
ScriptElementKind.typeElement,
ScriptElementKind.interfaceElement,
].includes(getTypeInfoRes.kind!)
) {
name = getTypeInfoRes.name;
comment = getTypeInfoRes.comment;
}
}

if (name) repl.outputStream.write(`${name}\n`);
if (comment) repl.outputStream.write(`${comment}\n`);
repl.displayPrompt();
Expand Down
21 changes: 21 additions & 0 deletions src/test/index.spec.ts
Expand Up @@ -411,6 +411,25 @@ test.suite('ts-node', (test) => {
);
});

test('REPL "type" command can be used on types', async () => {
const execPromise = exec(`${cmd} --interactive`);
execPromise.child.stdin!.end(
'type Foo = string | { x: 1 }\n' +
'.type Foo\n' +
'interface Bar { x: string; y: number; }\n' +
'.type Bar'
);
const { err, stdout } = await execPromise;
expect(err).to.equal(null);
expect(stdout).to.equal(
'> undefined\n' +
'> type Foo = string | {\n x: 1;\n}\n' +
'> undefined\n' +
'> interface Bar\n' +
'> '
);
});

function createReplViaApi() {
const stdin = new PassThrough();
const stdout = new PassThrough();
Expand Down Expand Up @@ -1654,6 +1673,7 @@ test.suite('ts-node', (test) => {
service.getTypeInfo('/**jsdoc here*/const x = 10', 'test.ts', 21)
).to.deep.equal({
comment: 'jsdoc here',
kind: 'const',
name: 'const x: 10',
});
});
Expand All @@ -1664,6 +1684,7 @@ test.suite('ts-node', (test) => {
service.getTypeInfo('/**jsdoc here*/const x = 10', 'test.ts', 0)
).to.deep.equal({
comment: '',
kind: undefined,
name: '',
});
});
Expand Down

0 comments on commit 6f7b2ff

Please sign in to comment.