Module or import types (#22592)

* Type side of import types

* Value side of import types

* Accept library changes

* Refined implementation, more tests

* Allow resolutions to be performed late if the resolution still results in a file already in the build

* Add another test case

* Add some jsdoc usages

* Allow nodebuilder to use import types where appropriate

* Parse & check generic instantiations

* use import types in nodebuilder for typeof module symbols

* Wire up go to definition for import types

* Accept updated type/symbol baselines now that symbols are wired in

* PR feedback

* Fix changes from merge

* Walk back late import handling

* Remove unused diagnostic

* Remove unrelated changes

* Use recursive function over loop

* Emit type arguments

* undo unrelated change

* Test for and support import type nodes in bundled declaration emit
This commit is contained in:
Wesley Wigham
2018-04-02 10:18:23 -07:00
committed by GitHub
parent 5c442419dc
commit 414bc49cc4
287 changed files with 3826 additions and 1279 deletions

View File

@@ -0,0 +1,42 @@
// @declaration: true
// @lib: es6
declare module "foo" {
interface Point {
x: number;
y: number;
}
export = Point;
}
const x: import("foo") = { x: 0, y: 0 };
declare module "foo2" {
namespace Bar {
interface I {
a: string;
b: number;
}
}
namespace Baz {
interface J {
a: number;
b: string;
}
}
class Bar {
item: Bar.I;
constructor(input: Baz.J);
}
}
let y: import("foo2").Bar.I = { a: "", b: 0 };
class Bar2 {
item: {a: string, b: number, c: object};
constructor(input?: any) {}
}
let shim: typeof import("foo2") = {
Bar: Bar2
};

View File

@@ -0,0 +1,11 @@
// @declaration: true
// @lib: es6
declare module "foo" {
interface Point {
x: number;
y: number;
}
export = Point;
}
const x: import("fo") = { x: 0, y: 0 }; // typo, error

View File

@@ -0,0 +1,14 @@
// @declaration: true
// @module: amd
// @outFile: bundle.js
// @filename: a/b/c.ts
export interface Foo {
x: 12;
}
// @filename: a/inner.ts
const c: import("./b/c").Foo = {x: 12};
export {c};
// @filename: index.ts
const d: typeof import("./a/inner")["c"] = {x: 12};
export {d};

View File

@@ -0,0 +1,18 @@
// @declaration: true
// @target: es6
// @filename: a.d.ts
export interface Foo {
a: string;
}
// @filename: b.d.ts
export interface Foo {
a: number;
}
// @filename: usage.ts
export function getFooFrom<T extends "./a" | "./b">(v: T): import(T).Foo {
return undefined as any;
}
export function getFooValueFrom<T extends "./a" | "./b">(v: T): import(T).Foo["a"] {
return undefined as any;
}

View File

@@ -0,0 +1,45 @@
// @declaration: true
// @lib: es6
// @filename: foo.ts
interface Point<T> {
x: number;
y: number;
data: T;
}
export = Point;
// @filename: foo2.ts
namespace Bar {
export interface I<T> {
a: string;
b: number;
data: T;
}
}
export namespace Baz {
export interface J<T> {
a: number;
b: string;
data: T;
}
}
class Bar<T> {
item: Bar.I<T>;
constructor(input: Baz.J<T>) {}
}
export { Bar }
// @filename: usage.ts
export const x: import("./foo")<{x: number}> = { x: 0, y: 0, data: {x: 12} };
export let y: import("./foo2").Bar.I<{x: number}> = { a: "", b: 0, data: {x: 12} };
export class Bar2<T> {
item: {a: string, b: number, c: object, data: T};
constructor(input?: any) {}
}
export let shim: typeof import("./foo2") = {
Bar: Bar2
};

View File

@@ -0,0 +1,29 @@
// @target: es6
// @outDir: ./out
// @allowJs: true
// @checkJs: true
// @filename: externs.d.ts
declare namespace MyClass {
export interface Bar {
doer: (x: string) => void;
}
}
declare class MyClass {
field: string;
static Bar: (x: string, y?: number) => void;
constructor(x: MyClass.Bar);
}
declare global {
const Foo: typeof MyClass;
}
export = MyClass;
// @filename: index.js
/**
* @typedef {import("./externs")} Foo
*/
let a = /** @type {Foo} */(/** @type {*} */(undefined));
a = new Foo({doer: Foo.Bar});
const q = /** @type {import("./externs").Bar} */({ doer: q => q });
const r = /** @type {typeof import("./externs").Bar} */(r => r);

View File

@@ -0,0 +1,42 @@
// @declaration: true
// @lib: es6
// @filename: foo.ts
interface Point {
x: number;
y: number;
}
export = Point;
// @filename: foo2.ts
namespace Bar {
export interface I {
a: string;
b: number;
}
}
export namespace Baz {
export interface J {
a: number;
b: string;
}
}
class Bar {
item: Bar.I;
constructor(input: Baz.J) {}
}
export { Bar }
// @filename: usage.ts
export const x: import("./foo") = { x: 0, y: 0 };
export let y: import("./foo2").Bar.I = { a: "", b: 0 };
export class Bar2 {
item: {a: string, b: number, c: object};
constructor(input?: any) {}
}
export let shim: typeof import("./foo2") = {
Bar: Bar2
};

View File

@@ -0,0 +1,43 @@
// @declaration: true
// @lib: es6
// @filename: foo.ts
interface Point {
x: number;
y: number;
}
export = Point;
// @filename: foo2.ts
namespace Bar {
export interface I {
a: string;
b: number;
}
}
export namespace Baz {
export interface J {
a: number;
b: string;
}
}
class Bar {
item: Bar.I;
constructor(input: Baz.J) {}
}
export { Bar }
// @filename: usage.ts
export const x: import("./fo") = { x: 0, y: 0 };
export let y: import("./fo2").Bar.I = { a: "", b: 0 };
export let z: import("./foo2").Bar.Q = { a: "", b: 0 };
export class Bar2 {
item: {a: string, b: number, c: object};
constructor(input?: any) {}
}
export let shim: typeof import("./fo2") = {
Bar: Bar2
};

View File

@@ -0,0 +1,8 @@
// @declaration: true
// @target: es6
// @filename: a.d.ts
export type LookAt = "./b";
// @filename: b.d.ts
export type Value = "yes";
// @filename: chainer.ts
export const x: import(import("./a").LookAt).Value = "yes";

View File

@@ -0,0 +1,9 @@
// @declaration: true
// @target: es6
// @noImplicitReferences: true
// @filename: a.d.ts
export type LookAt = "./b";
// @filename: b.d.ts
export type Value = "yes";
// @filename: chainer.ts
export const x: import(import("./a").LookAt).Value = "yes"; // expect outter import to fail, since b.d.ts isn't in the build

View File

@@ -0,0 +1,3 @@
// @declaration: true
// @target: es6
export const x: import({x: 12}) = undefined as any;

View File

@@ -0,0 +1,22 @@
/// <reference path="fourslash.ts" />
// @Filename: /ns.ts
/////*refFile*/export namespace /*refFoo*/Foo {
//// export namespace /*refBar*/Bar {
//// export class /*refBaz*/Baz {}
//// }
////}
// @Filename: /usage.ts
////type A = typeof import([|/*1*/"./ns"|]).[|/*2*/Foo|].[|/*3*/Bar|];
////type B = import([|/*4*/"./ns"|]).[|/*5*/Foo|].[|/*6*/Bar|].[|/*7*/Baz|];
verify.goToDefinition([
["1", "refFile"],
["2", "refFoo"],
["3", "refBar"],
["4", "refFile"],
["5", "refFoo"],
["6", "refBar"],
["7", "refBaz"],
]);

View File

@@ -7,4 +7,4 @@
// @Filename: b.js
////exports.x = 0;
verify.quickInfoAt("",'const x: typeof "/tests/cases/fourslash/b"');
verify.quickInfoAt("",'const x: typeof import("/tests/cases/fourslash/b")');