TypeScript Version: 2.1.1 / nightly (2.2.0-dev.201xxxxx)
Folder tree:
C:.
│ .gitignore
│ index.ts
│ package.json
│ tsconfig.json
│
├─.vscode
│ settings.json
│
└─@types
└─foo
index.d.ts
types-metadata.json
content of tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es5",
"lib": [ "es2015.promise", "es5", "scripthost"],
"typeRoots": [
"./@types"
]
}
}
content of foo/index.d.ts
declare module "foo" {
export function getElements(options:any, element: any, recurse:boolean, limit:number): any[];
}
content of index.ts
import * as foo from 'foo';
Expected behavior:
foo should be able to autocomplete
Actual behavior:
No action when use foo. to trigger autocomplete
cannot repro this locally, can you please provide more information about your setup?

@vladima I can reproduce this issue in the latest typescript 2.2.1. I have a folder custom-types where I have put definition files written by myself. If I copy these files to node_modules/@types folder, everything works as it should. But the typescript compiler doesn't pick up the types from the custom-types folder.
This is my tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es2017",
"sourceMap": true,
"strictNullChecks": true,
"sourceRoot": "src",
"outDir": "build",
"typeRoots": [
"./custom-types"
]
},
"exclude": [
"node_modules"
]
}
package.json
{
"name": "twilio-service",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"amqplib": "0.5.1",
"twilio": "2.11.1"
},
"devDependencies": {
"@types/amqplib": "0.5.1",
"typescript": "^2.2.1"
}
}
index.ts
import * as twilio from "twilio" // or import twilio = require("twilio") -> Both yield the same result.
const client = new twilio.RestClient("", "") // Client is of `any` type.
index.d.ts inside custom-types->twilio folder
export = TwilioLib
declare function TwilioLib(accountSID: string, authToken: string): TwilioLib.ITwilioClient
declare namespace TwilioLib {
interface IMessageOptions {
/**
* Any number twilio can deliver to.
*/
to: string
/**
* Any number you bought from Twilio and can use for outbound communication.
*/
from: string
/**
* Body of the SMS message.
*/
body: string
}
interface IMessageResponseData {
sid: string
date_created: string
date_updated: string
date_sent: string | null
account_sid: string
to: string
from: string
body: string
status: string
num_segments: string
num_media: string
direction: string
api_version: string
price: string | null
price_unit: string
error_code: string | null
error_message: string | null
uri: string
subresource_uris: { media: string }
}
interface ICallOptions {
/**
* Any number twilio can call
*/
to: string
/**
* A Twilio number you own
*/
from: string
/**
* A URL containing TwiML instructions for the call
*/
url: string
}
type CallStatus = "queued" | "initiated" | "ringing" | "answered" | "completed"
interface ICallResponseData {
sid: string
date_created: string
date_updated: string
parent_call_sid: string | null
account_sid: string
to: string
formatted_to: string
from: string
formatted_from: string
phone_number_sid: string
status: CallStatus
start_time: string | null
end_time: string | null
duration: string | null
price: string | null
direction: string
answered_by: string | null
api_version: string
forwarded_from: string | null
caller_name: string | null
uri: string
subresource_uris: {
notifications: string
recordings: string
}
}
interface ITwilioClient {
sendMessage(options: IMessageOptions, callback: ((err: Error, responseData: IMessageResponseData) => void))
makeCall(options: ICallOptions, callback: ((err: Error, responseData: ICallResponseData) => void))
}
export class RestClient {
constructor(accountSID: string, authToken: string)
sendMessage(options: IMessageOptions): Promise<IMessageResponseData>
makeCall(options: ICallOptions): Promise<ICallResponseData>
}
export function availablePhoneNumbers(country: string): any
export function request(requestOptions: any, cb?: (error, responseData) => void)
interface IWorkspaceTasks {
create(options: any)
}
interface IWorkspaceWorkers {
get(cb: (err, result) => void)
}
interface IWorkspaceStatistics {
get(options: any)
}
interface IWorkspace {
tasks: IWorkspaceTasks
workers: IWorkspaceWorkers
statistics: IWorkspaceStatistics
}
export class TaskRouterClient {
workspace: IWorkspace;
constructor(accountSID: string, authToken: string, workspaceSID: string)
}
export class TwimlResponse {
say(message: string): this
say(message: string, options: any): this
pause(options: any): this
play(soundURL: string): this
/**
* Exports the TwimlResponse to XML String.
*/
toString(): string
}
}
@mhegazy: Why was this closed? There didn't seem to be any resolution and I am experiencing the same issue.
I'm having the same issue.
If it helps, here's a repo where I'm having this issue.
I'm under the impression that typeRoots is ignored while resolving ambient modules and types. I have the following configuration:
{
"compilerOptions": {
"target": "es6",
"jsx": "preserve",
"strict": true,
"moduleResolution": "node",
"typeRoots" : ["./public"],
"types": ["node"],
"baseUrl": ".",
"paths": {},
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"preserveConstEnums": true,
"sourceMap": true,
"experimentalDecorators": true
},
"include": ["src/**/*"]
}
and I can still see that the node modules types are resolved from @types/node/index.d.ts
Module 'http' was resolved as locally declared ambient module in file '[...]/node_modules/@types/node/index.d.ts'.
They should not be resolved since there is nothing under ./public even if the if node is specified in types, is that right?
Per https://github.com/Microsoft/TypeScript/issues/13581#issuecomment-273923793, it looks like typeRoots are intended for global type definitions only. If you import something, Typescript will ignore the typeRoots directory when resolving types for it.
The solution for this is to use paths instead:
{
"compilerOptions": {
"moduleResolution": "node",
"module": "es6",
"target": "es6",
"baseUrl": "./",
"paths": {
"*" : ["my-type-roots/*"]
}
}
}
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.
Most helpful comment
@vladima I can reproduce this issue in the latest typescript 2.2.1. I have a folder
custom-typeswhere I have put definition files written by myself. If I copy these files tonode_modules/@typesfolder, everything works as it should. But the typescript compiler doesn't pick up the types from the custom-types folder.This is my tsconfig.json:
package.json
index.ts
index.d.ts inside custom-types->twilio folder