Import types in JS with var x = require('./mod') (#22161)

This commit is contained in:
Nathan Shively-Sanders 2018-03-08 11:11:51 -08:00 committed by GitHub
parent 99d866de4a
commit e4610e3418
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 370 additions and 1 deletions

View file

@ -2049,6 +2049,18 @@ namespace ts {
if (initializer) {
namespace = getSymbolOfNode(initializer);
}
if (namespace.valueDeclaration &&
isVariableDeclaration(namespace.valueDeclaration) &&
isCommonJsRequire(namespace.valueDeclaration.initializer)) {
const moduleName = (namespace.valueDeclaration.initializer as CallExpression).arguments[0] as StringLiteral;
const moduleSym = resolveExternalModuleName(moduleName, moduleName);
if (moduleSym) {
const resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym);
if (resolvedModuleSymbol) {
namespace = resolvedModuleSymbol;
}
}
}
}
symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning);
if (!symbol) {
@ -18133,7 +18145,7 @@ namespace ts {
// In JavaScript files, calls to any identifier 'require' are treated as external module imports
if (isInJavaScriptFile(node) && isCommonJsRequire(node)) {
return resolveExternalModuleTypeByLiteral(<StringLiteral>node.arguments[0]);
return resolveExternalModuleTypeByLiteral(node.arguments[0] as StringLiteral);
}
const returnType = getReturnTypeOfSignature(signature);

View file

@ -0,0 +1,32 @@
tests/cases/conformance/salsa/use.js(1,10): error TS2304: Cannot find name 'require'.
==== tests/cases/conformance/salsa/use.js (1 errors) ====
var ex = require('./ex')
~~~~~~~
!!! error TS2304: Cannot find name 'require'.
// values work
var crunch = new ex.Crunch(1);
crunch.n
// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
wrap.n
}
==== tests/cases/conformance/salsa/ex.js (0 errors) ====
export class Crunch {
/** @param {number} n */
constructor(n) {
this.n = n
}
m() {
return this.n
}
}

View file

@ -0,0 +1,56 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : Symbol(ex, Decl(use.js, 0, 3))
>'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.js, 0, 0))
// values work
var crunch = new ex.Crunch(1);
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>ex.Crunch : Symbol(Crunch, Decl(ex.js, 0, 0))
>ex : Symbol(ex, Decl(use.js, 0, 3))
>Crunch : Symbol(Crunch, Decl(ex.js, 0, 0))
crunch.n
>crunch.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
>f : Symbol(f, Decl(use.js, 4, 8))
>wrap : Symbol(wrap, Decl(use.js, 11, 11))
wrap.n
>wrap.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>wrap : Symbol(wrap, Decl(use.js, 11, 11))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
}
=== tests/cases/conformance/salsa/ex.js ===
export class Crunch {
>Crunch : Symbol(Crunch, Decl(ex.js, 0, 0))
/** @param {number} n */
constructor(n) {
>n : Symbol(n, Decl(ex.js, 2, 16))
this.n = n
>this.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>this : Symbol(Crunch, Decl(ex.js, 0, 0))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>n : Symbol(n, Decl(ex.js, 2, 16))
}
m() {
>m : Symbol(Crunch.m, Decl(ex.js, 4, 5))
return this.n
>this.n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
>this : Symbol(Crunch, Decl(ex.js, 0, 0))
>n : Symbol(Crunch.n, Decl(ex.js, 2, 20))
}
}

View file

@ -0,0 +1,61 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : typeof "tests/cases/conformance/salsa/ex"
>require('./ex') : typeof "tests/cases/conformance/salsa/ex"
>require : any
>'./ex' : "./ex"
// values work
var crunch = new ex.Crunch(1);
>crunch : Crunch
>new ex.Crunch(1) : Crunch
>ex.Crunch : typeof Crunch
>ex : typeof "tests/cases/conformance/salsa/ex"
>Crunch : typeof Crunch
>1 : 1
crunch.n
>crunch.n : number
>crunch : Crunch
>n : number
// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
>f : (wrap: Crunch) => void
>wrap : Crunch
wrap.n
>wrap.n : number
>wrap : Crunch
>n : number
}
=== tests/cases/conformance/salsa/ex.js ===
export class Crunch {
>Crunch : Crunch
/** @param {number} n */
constructor(n) {
>n : number
this.n = n
>this.n = n : number
>this.n : number
>this : this
>n : number
>n : number
}
m() {
>m : () => number
return this.n
>this.n : number
>this : this
>n : number
}
}

View file

@ -0,0 +1,31 @@
tests/cases/conformance/salsa/use.js(1,10): error TS2304: Cannot find name 'require'.
==== tests/cases/conformance/salsa/use.js (1 errors) ====
var ex = require('./ex')
~~~~~~~
!!! error TS2304: Cannot find name 'require'.
// values work
var crunch = new ex.Crunch(1);
crunch.n
// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
greatest.day
wrap.n
}
==== tests/cases/conformance/salsa/ex.d.ts (0 errors) ====
export type Greatest = { day: 1 }
export class Crunch {
n: number
m(): number
constructor(n: number)
}

View file

@ -0,0 +1,57 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : Symbol(ex, Decl(use.js, 0, 3))
>'./ex' : Symbol("tests/cases/conformance/salsa/ex", Decl(ex.d.ts, 0, 0))
// values work
var crunch = new ex.Crunch(1);
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>ex.Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33))
>ex : Symbol(ex, Decl(use.js, 0, 3))
>Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33))
crunch.n
>crunch.n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
>crunch : Symbol(crunch, Decl(use.js, 3, 3))
>n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
>f : Symbol(f, Decl(use.js, 4, 8))
>greatest : Symbol(greatest, Decl(use.js, 12, 11))
>wrap : Symbol(wrap, Decl(use.js, 12, 20))
greatest.day
>greatest.day : Symbol(day, Decl(ex.d.ts, 0, 24))
>greatest : Symbol(greatest, Decl(use.js, 12, 11))
>day : Symbol(day, Decl(ex.d.ts, 0, 24))
wrap.n
>wrap.n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
>wrap : Symbol(wrap, Decl(use.js, 12, 20))
>n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
}
=== tests/cases/conformance/salsa/ex.d.ts ===
export type Greatest = { day: 1 }
>Greatest : Symbol(Greatest, Decl(ex.d.ts, 0, 0))
>day : Symbol(day, Decl(ex.d.ts, 0, 24))
export class Crunch {
>Crunch : Symbol(Crunch, Decl(ex.d.ts, 0, 33))
n: number
>n : Symbol(Crunch.n, Decl(ex.d.ts, 1, 21))
m(): number
>m : Symbol(Crunch.m, Decl(ex.d.ts, 2, 13))
constructor(n: number)
>n : Symbol(n, Decl(ex.d.ts, 4, 16))
}

View file

@ -0,0 +1,61 @@
=== tests/cases/conformance/salsa/use.js ===
var ex = require('./ex')
>ex : typeof "tests/cases/conformance/salsa/ex"
>require('./ex') : typeof "tests/cases/conformance/salsa/ex"
>require : any
>'./ex' : "./ex"
// values work
var crunch = new ex.Crunch(1);
>crunch : Crunch
>new ex.Crunch(1) : Crunch
>ex.Crunch : typeof Crunch
>ex : typeof "tests/cases/conformance/salsa/ex"
>Crunch : typeof Crunch
>1 : 1
crunch.n
>crunch.n : number
>crunch : Crunch
>n : number
// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
>f : (greatest: { day: 1; }, wrap: Crunch) => void
>greatest : { day: 1; }
>wrap : Crunch
greatest.day
>greatest.day : 1
>greatest : { day: 1; }
>day : 1
wrap.n
>wrap.n : number
>wrap : Crunch
>n : number
}
=== tests/cases/conformance/salsa/ex.d.ts ===
export type Greatest = { day: 1 }
>Greatest : Greatest
>day : 1
export class Crunch {
>Crunch : Crunch
n: number
>n : number
m(): number
>m : () => number
constructor(n: number)
>n : number
}

View file

@ -0,0 +1,30 @@
// @allowJs: true
// @checkJs: true
// @strict: true
// @noEmit: true
// @Filename: ex.js
export class Crunch {
/** @param {number} n */
constructor(n) {
this.n = n
}
m() {
return this.n
}
}
// @Filename: use.js
var ex = require('./ex')
// values work
var crunch = new ex.Crunch(1);
crunch.n
// types work
/**
* @param {ex.Crunch} wrap
*/
function f(wrap) {
wrap.n
}

View file

@ -0,0 +1,29 @@
// @allowJs: true
// @checkJs: true
// @strict: true
// @noEmit: true
// @Filename: ex.d.ts
export type Greatest = { day: 1 }
export class Crunch {
n: number
m(): number
constructor(n: number)
}
// @Filename: use.js
var ex = require('./ex')
// values work
var crunch = new ex.Crunch(1);
crunch.n
// types work
/**
* @param {ex.Greatest} greatest
* @param {ex.Crunch} wrap
*/
function f(greatest, wrap) {
greatest.day
wrap.n
}