Defining TypeScript typing for module gives TS2665? - syntax

Trying to migrate from old tsd.json to typings.json. Previous my .d.ts had:
declare var modname: modname.modname;
declare module modname {
export interface modname {
new (): modname;
}
export interface foo {
bar: string;
}
}
declare module "mod-name" {
export = modname;
}
Then due to errors I changed the first lines to:
declare var modname: modname.modname;
declare namespace modname {
But then got:
TS2665: Module augmentation cannot introduce new names in the top level scope.
Maybe I am meant to install the Typings differently? - I notice strange scaffolding being automatically added to my definition files, which are installed with:
typings install github:user/typ/mod-name/mod-name.d.ts --save

TS2665: Module augmentation cannot introduce new names in the top level scope.
This no longer an error in the Latest Master version of typescript npm install typescript#next
Consider using this version for various reasons : https://basarat.gitbooks.io/typescript/content/docs/getting-started.html#nightly-typescript

Related

usage of JS plugins with webpack

I am trying to reconfigure my Symfony 3 project to use webpack encore instead of normal asstets. I am a little stuck with this.
For one part of the application I developed some JS plugins which inherits from Kube (a CSS and JS Framework I am unsing). Here is an exmaple:
(function (Kube) {
Kube.Assignment = function (element, options) {
this.namespace = 'assignment';
this.defaults = {
//...
};
Kube.apply(this, arguments);
this.start();
};
Kube.Assignment.prototype = {
start: function () {
//...
}
};
Kube.Assignment.inherits(Kube.Distribution);
Kube.Plugin.create('Assignment');
Kube.Plugin.autoload('Assignment');
}(Kube));
Unfortunatly Kube is not recognized.
The module 'imperavi-kube' is installed via yarn and is imported via
let Kube = require('imperavi-kube');
I am getting the following error: TypeError: Kube.Assignment.inherits is not a function
Propably this is not a issue of the Kube Framework but somthing about handeling JS plugins with webpack.
Inside the Kube module there is a class 'Kube' defined with a prototype. The Prototype ends with window.Kube = Kube;
Try to import Kube like this:
import * as Kube from <your path> or <alias> or <module name>
I may be wrong, but as far as I remember sometimes it works a bit differently.

Typescript reference comment for working

I am using Visual Studio 2013 Ultimate Update 4 and Typescript.
I have a class like MyClass.ts:
/// <reference path="interfaces/IMyClass"/>
export = MyModule;
module MyModule {
class MyClass {
constructor(myObject: IMyClass){....}
...
}
}
And another MyInterface.ts:
export = MyModule;
module MyModule {
interface IMyClass {
...
}
}
VS2013 is not acknowledging the IMyClass reference in the MyClass file (no intellisense either), but the reference is acting like VS can see it (no red underlines saying it can't find the file).
If I change the interface filename to MyInterface.d.ts, it does the same thing.
If I change the interface inside MyInterface.d.ts to this:
//export = MyModule ;
declare module MyModule {
interface IMyClass {
...
}
}
it fails as well.
If I change the interface inside MyInterface.d.ts to this:
//export = MyInterfaces ;
declare module MyInterfaces {
interface IMyClass {
...
}
}
it works.
Am I missing something? So we can only use reference comments for .d.ts files and the exported module names can be the same??
I'm finding a lot of the stuff around modules in typescript to be confusing.
Thanks in advance.
VS2013 is not acknowledging the IMyClass reference in the MyClass file (no intellisense either),
The modules MyModule between two TypeScript files that use external modules are distinct. And therefore you don't get interface IMyClass available in the second files MyModule.
Tip: You might want to review internal vs. external modules in TypeScript (hint: don't use internal ones if you are using external modules). https://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1

Typescript split solution into several projects

I used ScriptSharp before it was frozen. Since TypeScript is a developing OOP language I decided to try it. I use visual studio (if it matters). I have troubles making simple things I used to do in ScriptSharp. I didn't expect it would be that difficult.
What I want to do:
Create project A (Class Library Project) with module AssemblyA. AssemblyA module will have
some exported classes.
Create project B (Class Library Project) with module AssemblyB. AssemblyB will reference
AssemblyA types and use them as parameter types and etc.
Can you give me some guide how to make it work or sample? Thanks.
UPDATE:
What's for I can add reference to another typescript project? It would be great if output of referenced project was copied to that project.
Rather than having assemblies and modules, you have modules that can be organised into namespace-like hierarchies:
Internal Modules
Internal Module Example:
module AssemblyA {
export module ModuleA {
export class Example {
}
}
export module ModuleB {
export class Example {
}
}
}
var x = new AssemblyA.ModuleA.Example();
var y = new AssemblyA.ModuleB.Example();
You can also define these internal modules across multiple files...
modulea.ts
module AssemblyA {
export module ModuleA {
export class Example {
}
}
}
moduleb.ts
///<reference path="./modulea.ts" />
module AssemblyA {
export module ModuleB {
export class Example {
}
}
}
app.ts
///<reference path="./modulea.ts" />
///<reference path="./moduleb.ts" />
var x = new AssemblyA.ModuleA.Example();
var y = new AssemblyA.ModuleB.Example();
External Modules
And if you want to write really large applications, you can use external modules (where the file represents the module).
assemblya/modulea.ts
export class Example {
}
assemblya/moduleb.ts
export class Example {
}
app.ts
import ModuleA = require('./assemblya/modulea');
import ModuleA = require('./assemblya/modulea');
var x = new ModuleA.Example();
var y = new ModuleB.Example();
I found a workaround for my problem:
In project AssemblyA:
Specify "Combine javascript output into file" to "..\AssemblyB\AssemblyA.js".
Set up Generate Declaration files into true.
In project AssemblyB:
Add reference for intellisense in app.ts ///<reference path="../AssemblyA/AssemblyA.d.ts" />
Add reference to generated file in html: <script src="AssemblyA.js"></script>
In project B you can use any namespace aliases (for example: import AssemblyANS2 = AssemblyA.NS2;) or fully qualified name.
Put classes in different files, Use same module name and there is no need to refer to ts files.
What I didn't like is that referencing project doesn't make any sense, but I wanted steps 1-2-3-4 to be done automatically after adding reference.
Also "Redirect javascript output to directory" setting doesn't work when "Combine javascript output into one file" is specified. It's also weird that I can specify file path in second options. I expected these settings to be combined with Path.Combine.
Maybe my solution is not ideal, but it's exactly what I need. Feel free to suggest better idea.

How do I reference a Typescript enum inside a definition file

I am using Visual Studio 2013 with update 4 and Typescript 1.3 installed.
If I have a typescript file, like so:
MyEnums.ts:
export = MyEnumModule;
module MyEnumModule {
export enum AnEnum { RED, BLUE, GREEN }
}
And I have a definitions file like so:
MyDefinitions.d.ts:
declare module MyDefinitions {
interface ISomeInterface {
aProperty: string;
aMethod: () => void;
aColor: MyEnumModule.AnEnum;
}
}
I basically get an error of "Cannot find name 'MyEnumModule'"
This enum file works fine when referenced from typescript files. For instance:
SomeCode.ts:
export = MyCode;
import MyEnums = require('MyEnums');
module MyCode{
export class MyClass implements ISomeInterface {
public aColor: MyEnums.AnEnum = MyEnums.AnEnum.RED;
...and so on
My understanding is that adding either /// <reference ... or an import will not work for a .d.ts file (I tried just to be sure and it didn't appear to work either way).
Does anyone know how to reference an enum in a definition file like this?
Thanks in advance.
--Update:
Here is the error I see after trying Steve Fenton recommendations below (with a sample project I just made).
MyDefinitions.ts:
import MyEnumModule = require('../App/MyEnums');
declare module MyDefinitions {
interface ISomeInterface {
aProperty: string;
aMethod: () => void;
aColor: MyEnumModule.AnEnum;
}
}
MyEnums.ts:
export = MyEnumModule;
module MyEnumModule {
export enum AnEnum { RED, BLUE, GREEN }
}
MyClass.ts:
export = MyCode;
import MyImport = require('MyEnums');
module MyCode {
export class MyClass implements MyDefinitions.ISomeInterface {
public aColor: MyImport.AnEnum = MyImport.AnEnum.RED;
constructor() { }
aProperty: string = "";
aMethod: () => void = null;
}
}
Folder structure:
App
-MyClass.ts
-MyEnums.ts
Defintions
-MyDefintions.d.ts
Inside MyClass.ts MyDefinitions.ISomeInterface is underlined in red with hover warning "Cannot find name MyDefinitions".
I have AMD set for the project
Does anyone know how to reference an enum in a definition file like this?
There are workaround as Steve Fenton pointed out, but the system isn't designed for this. You should reference other definition files in your definition file and not reference an *implementation file * (MyEnum.ts) in a definition file.
I had a check on this and the following definition works for me, although I must admit I have never referenced "actual" code from "definition" code - but I can't think of any reason not to.
import MyEnumModule = require('MyEnumModule');
declare module MyDefinitions {
interface ISomeInterface {
aProperty: string;
aMethod: () => void;
aColor: MyEnumModule.AnEnum;
}
}
On mixing definitions and real implementations...
The type system in TypeScript is a design time and compile-time tool. When the type information is constructed at design time it makes no difference whether the type information is inferred from implementation code, taken from annotations that decorate implementations or come from an ambient declaration.
There are many use cases for mixing implementation code and ambient declarations - if you are migrating a million-line JavaScript program to TypeScript, you may not be able to migrate it from the bottom-most dependency upwards. Also, you can place ambient declarations inside of normal files - not just definition files - if you have a large program, you may not even know whether a type you place in an ambient declaration is "real" or "ambient".
The only difference between implementation code types and ambient declaration types is that the type information is right next to the implementation in real code files, and in a separate file for ambient declarations.
So... if you are having a problem using real implemented types in your ambient declaration, it is most likely caused by something that can be fixed. The example I supplied above works in a project I have in Visual Studio 2013, Update 4 - with TypeScript build configuration set to compile AMD modules. If you can share the exact details of the problem, I'm happy to help you get it working.
Having said this - if you are creating a type definition for trivial amounts of code, pasting them into a .ts file may even be faster than writing the definition - so you should make a case-by-case decision on where to spend the effort.

Is it possible require file content "as is" in TypeScript?

Typescript defines comment with xml tag <reference path=""/> to source local files to current file. But that tag could be placed only in file header before declaring any structures such us other modules.
So,
// File1.ts - correct
///<reference path="./Common.ts"/>
module Test {
export class TestClass {
}
}
// File2.ts - incorrect
module Test {
///<reference path="./Common.ts"/> // <<< Here is an compile error
export class TestClass {
}
}
Is it possible to source content of other typescript file to custom place of current file?
No. You cannot require code inplace as you have already found:
// File2.ts - incorrect
module Test {
///<reference path="./Common.ts"/> // <<< Here is an compile error
export class TestClass {
}
}
However you can effectively get the same effect by using functions.
// File1.ts - correct
///<reference path="./Common.ts"/>
module Test {
callAFunctionFoundInCommon();
export class TestClass {
}
}
In the latest version of TypeScript, it is not necessary to reference files manually like that. You can simply remove the reference and TypeScript will be able to figure everything out automatically.

Resources