使用const作为对象和打字稿中的类型?

时间:2016-10-27 21:43:37

标签: typescript

我们需要将一个类用作对象和接口。这个类有一个非常长的名字,所以我们把它扔到一个常数,但后来发生了奇怪的事情:

class MyClassWithAReallyLongNameThatIsAnnoyinToUse {
    constructor(public name: string) {}
    static className = "SomeThing:MyClassWithAReallyLongNameThatIsAnnoyinToUse";
}

// Convenience const to shorten
const MyClassConst = MyClassWithAReallyLongNameThatIsAnnoyinToUse;

let someFunction = (staticClassObject: Object, callback) =>  {};

// this errors, saying 'Cannot find name MyClassConst'
someFunction(MyClassConst, (cmd: MyClassConst) => { /* do some thing */ });

但是,如果我们在type正下方引用const别名,则可行:

class MyClassWithAReallyLongNameThatIsAnnoyinToUse {
    constructor(public name: string) {}
    static className = "SomeThing:MyClassWithAReallyLongNameThatIsAnnoyinToUse";
}

// Convenience const to shorten
const MyClassConst = MyClassWithAReallyLongNameThatIsAnnoyinToUse;
type MyClassConst = MyClassWithAReallyLongNameThatIsAnnoyinToUse;  // <<<<<<<<<<<<<

let someFunction = (staticClassObject: Object, callback) =>  {};

// this is fine
someFunction(MyClassConst, (cmd: MyClassConst) => { /* do some thing */ });

但这看起来很奇怪。我们不仅要改变一个const,而且我们用相同的赋值来定义相同的东西两次,只是不同的关键词;而且因为在const的每个位置使用普通的长类名称反而完全正常。当类通过const代理时,它似乎只会引发一个问题(或者让let或var,也尝试它们)。

这只是我们必须要接受的一个怪癖,还是我们可以调用const来获取类型?还是我们还缺少另一项任务?

1 个答案:

答案 0 :(得分:1)

类型别名(如接口)在编译过程中不存在,并且不是已编译的javascript的一部分 您不能将类型别名分配给变量,不能将其作为参数传递给函数,它在运行时不存在。

另一方面,您不能将变量用作类型:

let a = "string";
let b: a; // Error: Cannot find name 'a'

您只是以不同的方式使用它们,因此在命名类型别名和同名变量时没有冲突。
与接口一样工作:

const MyString = "astring";
interface MyString {
    doSomethingSpecial();
}

因为MyClassConst const没有“变异” 类(和枚举)可以用作类型,但它们也存在于运行时,因此您可以将它们分配给变量或将它们传递给函数。
因此,尝试此操作时出错:

type MyType = string; // Error: Duplicate identifier 'MyType'
class MyType {} // Error: Duplicate identifier 'MyType'

enum MyOtherType {} // Error: Duplicate identifier 'MyOtherType'
let MyOtherType = 3; // Error: Duplicate identifier 'MyOtherType'

无论如何,您应该避免使用docs for the any type中所述的Object类型:

  

任何类型都是使用现有JavaScript的强大方式,   允许您逐步选择加入并选择退出类型检查   汇编。 您可能希望Object扮演类似的角色   用其他语言做。但是Object类型的变量只允许你   为它们分配任何值 - 你不能调用任意方法   他们,甚至是那些实际存在的人

所以你最好使用any,但你也可以这样做:

class MyClassWithAReallyLongNameThatIsAnnoyinToUse {
    constructor(public name: string) {}
    static className = "SomeThing:MyClassWithAReallyLongNameThatIsAnnoyinToUse";
}

type MyClassConst = MyClassWithAReallyLongNameThatIsAnnoyinToUse;
type MyClassConstructor = {
    new (name: string): MyClassConst;
    className: string;
}
type MyClassHandler = (cmd: MyClassConst) => void;
const MyClassConst = MyClassWithAReallyLongNameThatIsAnnoyinToUse;

let someFunction = (staticClassObject: MyClassConstructor, callback: MyClassHandler) => { };

someFunction(MyClassConst, (cmd: MyClassConst) => { /* do some thing */ });

const MyString = "astring";
interface MyString {
    doSomethingSpecial();
}

code in playground