Skip to content
This repository has been archived by the owner on Dec 25, 2018. It is now read-only.

import from TypeScript.NET breaks compilation #67

Closed
lukos opened this issue Oct 25, 2017 · 8 comments
Closed

import from TypeScript.NET breaks compilation #67

lukos opened this issue Oct 25, 2017 · 8 comments

Comments

@lukos
Copy link

lukos commented Oct 25, 2017

This is likely to be a newb problem that needs some documentation, but I have an interface that is referenced in another interface within the same namespace (in separate files):

IBusinessLayer.ts:

/// <reference path="IClientUtilities.ts" />

namespace SharedBusinessLayer {
	export interface IBusinessLayer {
             ClientUtilities: IClientUtilities;
	}
}

IClientUtilities.ts

import Dictionary from "typescript-dotnet-umd/System/Collections/Dictionaries/Dictionary"

namespace SharedBusinessLayer {
	export interface IClientUtilities {
	}	
}

BUT, when I include the import line into the top of IClientUtilities (to return from a property that is not yet declared), the ts build fails for IBusinessLayer "error TS2304: Cannot find name 'IClientUtilities'". If I remove the import line, the build succeeds.

I'm guessing that the import is screwing with my namespaces but I don't know how to fix it.

@electricessence
Copy link
Owner

I don't believe this has anything to do with TypeScript.NET. I think it is due to mixing namespaces with modules.

https://www.typescriptlang.org/docs/handbook/namespaces.html
This information might be obsolete as it's not really using modules as you are attempting.

You might notice that TypeScript.NET has ZERO namespaces. That's because the idea behind 'modules' is that namespaces simply don't need to exist.

Also... Interfaces are a funny thing. They don't need to be part of a real module. You can define an exported namespace by itself within a *d.ts file and it won't need to compile. Interfaces don't generate real JS code.

@lukos
Copy link
Author

lukos commented Oct 25, 2017

Thanks for the reply. It is very possible that the problem you described is correct although I don't understand how it breaks compilation just by importing the type. I would understand if I was trying to use the Dictionary type and it couldn't resolve properly.
I believe there are changes in later typescript versions where "internal modules" are now namespaces so I will have to investigate some more, it will be a shame if I can't use your great library.

@electricessence
Copy link
Owner

electricessence commented Oct 25, 2017

If you notice the examples in the link, they are using old-style ///<reference> tags instead of modules. These are not normally 'mixed' with modules.

If you are trying to build a monolith library then you can do what you're thinking, but you would need to throw out modules all together...

A long time ago, TypeScript.NET would have worked with namespaces, but now TypeScript.NET is all modules. If you are going to use it, try it without namespaces.

In a modular world, "think modules". Folders can be your namespaces. But the idea behind modules is that namespaces simply aren't necessary. You can import a specific 'module' and name it however you want without concern for collision.

@lukos
Copy link
Author

lukos commented Oct 27, 2017

OK. So I removed all my namespaces and am trying to use Enumerable and the TypeScript compiler is erroring. The errors are:

C:/Users/luke/source/repos/nodespeedtest/node_modules/typescript-dotnet-umd/System.Linq/Linq.d.ts(16,22): error TS2420:
Class 'InfiniteLinqEnumerable<T>' incorrectly implements interface 'IInfiniteEnumerable<T>'.
  Types of property 'doAction' are incompatible.
    Type '{ (action: ActionWithIndex<T> | PredicateWithIndex<T> | SelectorWithIndex<T, number> | SelectorWi...' is not a
ssignable to type '{ (action: ActionWithIndex<T> | PredicateWithIndex<T> | SelectorWithIndex<T, number> | SelectorWi...'
. Two different types with this name exist, but they are unrelated.
      Type 'InfiniteLinqEnumerable<T>' is not assignable to type 'IInfiniteEnumerable<T>'.
        Types of property 'doAction' are incompatible.
          Type '{ (action: ActionWithIndex<T> | PredicateWithIndex<T> | SelectorWithIndex<T, number> | SelectorWi...' is
 not assignable to type '{ (action: ActionWithIndex<T> | PredicateWithIndex<T> | SelectorWithIndex<T, number> | Selector
Wi...'. Two different types with this name exist, but they are unrelated.
            Type 'InfiniteLinqEnumerable<T>' is not assignable to type 'ILinqEnumerable<T>'.
              Property 'skipWhile' is missing in type 'InfiniteLinqEnumerable<T>'.

There are also two other errors related to skip(), which are similar and related to LinqEnumerable is not assignable to type 'ILinqEnumerable

I'm not sure if it is related but if I ignore these errors and attempt to run the node server, when I call the following code I get another error. I'm not sure whether the compiler error is caused by a coding error or whether the runtime error is related to a problem with the typescript-dotnet package code?

import Enumerable from 'typescript-dotnet-umd/System.Linq/Linq';

// etc

var datahash: string;
let myEnumerable = Enumerable.from(user.Claims);       // <-- Error is here
if (user.Claims != null && myEnumerable.any(c=>c.Type == "datahash"))
{
    datahash = myEnumerable.where(c => c.Type == "datahash").firstOrDefault().Value;
}

User.ts:

import List from "typescript-dotnet-umd/System/Collections/List";
import { Claim } from './Claim';

export class User {
    private claims: List<Claim>;

    get Claims(): List<Claim> {
        return this.claims;
    }

    set Claims(claims: List<Claim>) {
        this.claims = claims;
    }
}

error: UnsupportedEnumerableException: Unsupported enumerable.

@electricessence
Copy link
Owner

Ok. I will look into this. I've had to do some refactoring previously to get the interfaces to compile properly with the Linq library. Make sure you have the latest version. I will update within 24 hours.

@electricessence
Copy link
Owner

electricessence commented Oct 28, 2017

So this may be a new TS version problem.
It's an absolute nightmare upgrading past TS 2.3.2.
I've been waiting for the compiler to stop running out of memory for me to upgrade.
I'll keep trying but just to report in. My current build not only builds and runs perfectly without error, I did test Enumerable.from(list) without incident also.

Side note, you can do this as well:

var e = Enumerable(list); // same as Enumerable.from(list);

In a node (commonjs) environment:

let datahash  = list.linq.where(x=>x.Type=="datahash").firstOrDefault().Value;

in other environments

(AMD loaded or non-commonJS):

let datahash;
list.linqAsync(e=>{
   datahash = e.where(x=>x.Type=="datahash").firstOrDefault().Value;
});

And you can:

let isLinqReady = false;
let linq = list.linqAsync(e=>{isLinqReady=true;});
////////////////// Later on....
if(!linq && isLinqReady) linq = list.linq;
let datahash  = linq.where(x=>x.Type=="datahash").firstOrDefault().Value;

You might be asking, why not include it by default? The reason is modularity. The Linq module is HUGE and some people may not use it. So especially for web, it's not included by default.

Here's the helper code implementation:
https://github.com/electricessence/TypeScript.NET/blob/master/source/System/Collections/CollectionBase.ts#L425-L496

@electricessence
Copy link
Owner

v4.9.9 released to npm... Should fix the issues you encountered.
It now compiles with more recent TS versions like 2.5.3 and even 2.7.0-dev. But I kept the required version at ^2.3.2 because I still encounter a heap memory error when trying to compile my dist packages.
microsoft/TypeScript#18411

Please try the latest version and tell me if its working for you. I'm guessing you have 2.5.3 and it is a bit more strict and found inconsistencies with the Enumerable.d.ts file and Linq.ts.

Thanks for bringing this to my attention.

@electricessence
Copy link
Owner

@lukos did you get it working?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants