Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type aliases don't work with classes #2552

Closed
zpdDG4gta8XKpMCd opened this issue Mar 30, 2015 · 7 comments
Closed

Type aliases don't work with classes #2552

zpdDG4gta8XKpMCd opened this issue Mar 30, 2015 · 7 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@zpdDG4gta8XKpMCd
Copy link

class A {}
type B = A;
var b = new B(); // <--- Cannot find name 'B'.
@mhegazy
Copy link
Contributor

mhegazy commented Mar 30, 2015

That is because it is a type alias not just an alias. you are aliasing the type part of the class A (i.e. the instance type of objects created by calling new A()). this is similar to using an interface, e.g.:

class A {}
interface B extends A {} 

As opposed to the value side of the class (i.e. the constructor function A):

class A {}
var B = A;
var b = new B(); // b is of type A
var c: B; // Error Can not find name B, B is not a type

if you just want to give A a different name, i.e. alias all meanings of A (instance type and constructor function), use:

module M {
    export class A {}
}
import B = M.A;
var b = new B(); 

@mhegazy mhegazy added the Question An issue which isn't directly actionable in code label Mar 30, 2015
@zpdDG4gta8XKpMCd
Copy link
Author

That is because it is a type alias not just an alias

this is odd.. I have a practical situation, an ugly looking class mwsb.Workspace<dbls.BeamLoadingWorkspaceSettings, dblt.WorkareaType, WardSettingsManager<pl.WokareaEmbodiment>> that I wish I could alias to a nicer looking one for the sake of dealing with a less messier type signature, now you say, well you can but you cannot, turns out type aliases as they are are as half baked as type unions, limited specific case only driven features

what does it take to get genuine aliases?

@danquirk
Copy link
Member

You have to choose whether you want to alias the value, the type, or both. There is different syntax for each.

module SomeLongName {
    export class WhatAnAwfulName {
        foo: string;
    }
}

var ctor = SomeLongName.WhatAnAwfulName; // use var to alias the constructor function
var anAwfulThing = new ctor(); // hover over anAwfulThing and see 'SomeLongName.WhatAnAwfulName'
var anotherAwfulThing: ctor; // error: ctor is not a type, it's just a function

type ctor2 = SomeLongName.WhatAnAwfulName; // use type to alias the type of SomeLongName.WhatAnAwfulName
var anAwfulThing2 = new ctor2(); // error, ctor2 is not a function, it's a type
var anotherAwfulThing2: ctor2; // ok, hover over anAwfulThing2 and see 'SomeLongName.WhatAnAwfulName'

import ctor3 = SomeLongName.WhatAnAwfulName; // use import to alias all meanings, ctor3 is now a function and a type
var anAwfulThing3 = new ctor3(); // ok, ctor3 is a function
var anotherAwfulTHing3: ctor3; // ok, ctor3 is also a type

@zpdDG4gta8XKpMCd
Copy link
Author

@danquirk

so basically i am looking for the same type aliases (or whatever they really are) C# has https://msdn.microsoft.com/en-us/library/sf0df423.aspx

case 3 from your example would have been exactly what i am after if i could import a type peppered with type arguments:

import NiceName = SomeLongName.WhatAnAwfulName<number, boolean, string, Date>

which, as we know, i can't

so the working alternative is to pass around a type-instance-type (case2) and a constructor function (case1) together.. well, i'd be better off just inheriting from an ugly type as i used to do before type aliases came in

@DanielRosenwasser DanielRosenwasser added By Design Deprecated - use "Working as Intended" or "Design Limitation" instead and removed Question An issue which isn't directly actionable in code labels Mar 31, 2015
@CyrusNajmabadi
Copy link
Contributor

@Aleksey-Bykov You can do something close to that with:

import NiceName = SomeLongName.WhatAnAwfulName;
...

var v = new NiceName<number, boolean, string, Date>;

When you're importing, you're not importing any one instantiation of a type. You're getting the constructor function. Something that you can use to create instantiations of any form. That's something strictly more powerful than the C# form. Indeed, in C# it's annoying because you can't do any of the following:

using SysList = System.Collections.Generic.List;
using SysList = System.Collections.Generic.List<T>;
using SysList<T> = System.Collections.Generic.List<T>;

Instead, using aliases in C# can only alias an instantiation of a generic.

@zpdDG4gta8XKpMCd
Copy link
Author

@CyrusNajmabadi in my case the ugliness comes not from the name of the type itself, but from its list of type arguments that, according to your suggestion, i still have to mention every time, so it doesn't really solve the problem, consider:

// before

var a : mwsb.Workspace<dbls.BeamLoadingWorkspaceSettings, dblt.WorkareaType, WardSettingsManager<pl.WokareaEmbodiment>>;

// after

import Workspace = mwsb.Workspace;

var b : Workspace<dbls.BeamLoadingWorkspaceSettings, dblt.WorkareaType, WardSettingsManager<pl.WokareaEmbodiment>>;

// does it look much better? let's  try one more time

import Workspace = mwsb.Workspace;
import Settings = dbls.BeamLoadingWorkspaceSettings;
import Type = dblt.WorkareaType;
import Embodiment = pl.WokareaEmbodiment;

var c : Workspace<Settings, Type, WardSettingsManager<Embodiment>>;

// that was the best one can get instead of a hypothetical type alias

type Workspace = mwsb.Workspace<dbls.BeamLoadingWorkspaceSettings, dblt.WorkareaType, WardSettingsManager<pl.WokareaEmbodiment>>

var d : Workspace;

// practical solution (at the price of an unnecessary runtime overhead)

class Workspace extends mwsb.Workspace<dbls.BeamLoadingWorkspaceSettings, dblt.WorkareaType, WardSettingsManager<pl.WokareaEmbodiment>> {

}

var e: Workspace

as for C# although you are right, but the use case i am looking for in TypeScript is precisely supported by C#, namely getting an alias to the type (be it an interface or a class) with all its type parameters resolved

to me not being able to refer to a type alias from another file is a much greater annoyance in C#

@RyanCavanaugh
Copy link
Member

Continuing discussion in referenced issue

lgarron added a commit to cubing/alg.cubing.net that referenced this issue Dec 31, 2016
This allows direct instantiation in TypeScript.
See microsoft/TypeScript#2552 and linked issues.
@microsoft microsoft locked and limited conversation to collaborators Jun 18, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead
Projects
None yet
Development

No branches or pull requests

6 participants