组合 class 和接口类型
Combined class and interface type
在 Javascript(在 WScript 或 HTA 下)中,我会编写以下模式:
var fso = new ActiveXObject('Scripting.FileSystemObject');
var ext = fso.GetExtensionName('C:\test.txt'); //returns 'txt'
var badResult = fso.NonExistentMethod(); //raises a runtime error
使用 TypeScript,我可以声明一个接口来防止此类错误:
module Scripting {
export interface FileSystemObject {
GetExtensionName(path: string): string,
GetParentFolderName(path: string): string
}
}
var fso: Scripting.FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var ext = fso.GetExtensionName('C:\test.txt'); //ext is recognized as a string
//var badResult = fso.NonExistentMethod(); //will not compile
但是,我想像这样初始化 fso
变量:
var fso = new Scripting.FileSystemObject();
并让类型系统自动推断 fso
的类型是接口 Scripting.FileSystemObject
.
这可以做到吗?
1) 无法在接口中添加构造函数,因为接口只是对象的形状,而不是它的实现。
2) 我考虑创建一个内部接口,并使用 class 和构造函数扩展接口:
module Scripting {
interface Internal {
GetExtensionName(path: string): string;
GetParentFolderName(path: string): string;
}
export class FileSystemObject extends Internal {
constructor() {
return new ActiveXObject('Scripting.FileSystemObject');
}
}
}
但是如果不调用接口没有的基类型构造函数,就不能将构造函数添加到扩展 class。
3) 我不能有一个declared
class,因为构造函数仍然是一个实现,不能写成declared
class,这是一个环境上下文。
deduce that the type of fso is the interface Scripting.FileSystemObject.Can this be done?
当然可以。只需声明一些在使用 new
调用时将 return 为正确类型的东西。即下面的export var FileSystemObject: { new (): FileSystemObject };
:
declare module Scripting {
export interface FileSystemObject {
GetExtensionName(path: string): string;
GetParentFolderName(path: string): string;
}
export var FileSystemObject: { new (): FileSystemObject };
}
var fso: Scripting.FileSystemObject = new Scripting.FileSystemObject();
var ext = fso.GetExtensionName('C:\test.txt'); //ext is recognized as a string
var badResult = fso.NonExistentMethod(); //will not compile
UPDATE 要自己实现类似的功能,您可以这样做:
module Scripting {
export interface FileSystemObject {
GetExtensionName(path: string): string;
GetParentFolderName(path: string): string;
}
export var FileSystemObject: { new (): FileSystemObject } = <any>function(){
return new ActiveXObject('Scripting.FileSystemObject');
};
}
var fso: Scripting.FileSystemObject = new Scripting.FileSystemObject();
var ext = fso.GetExtensionName('C:\test.txt'); //ext is recognized as a string
var badResult = fso.NonExistentMethod(); //will not compile
在 Javascript(在 WScript 或 HTA 下)中,我会编写以下模式:
var fso = new ActiveXObject('Scripting.FileSystemObject');
var ext = fso.GetExtensionName('C:\test.txt'); //returns 'txt'
var badResult = fso.NonExistentMethod(); //raises a runtime error
使用 TypeScript,我可以声明一个接口来防止此类错误:
module Scripting {
export interface FileSystemObject {
GetExtensionName(path: string): string,
GetParentFolderName(path: string): string
}
}
var fso: Scripting.FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var ext = fso.GetExtensionName('C:\test.txt'); //ext is recognized as a string
//var badResult = fso.NonExistentMethod(); //will not compile
但是,我想像这样初始化 fso
变量:
var fso = new Scripting.FileSystemObject();
并让类型系统自动推断 fso
的类型是接口 Scripting.FileSystemObject
.
这可以做到吗?
1) 无法在接口中添加构造函数,因为接口只是对象的形状,而不是它的实现。
2) 我考虑创建一个内部接口,并使用 class 和构造函数扩展接口:
module Scripting {
interface Internal {
GetExtensionName(path: string): string;
GetParentFolderName(path: string): string;
}
export class FileSystemObject extends Internal {
constructor() {
return new ActiveXObject('Scripting.FileSystemObject');
}
}
}
但是如果不调用接口没有的基类型构造函数,就不能将构造函数添加到扩展 class。
3) 我不能有一个declared
class,因为构造函数仍然是一个实现,不能写成declared
class,这是一个环境上下文。
deduce that the type of fso is the interface Scripting.FileSystemObject.Can this be done?
当然可以。只需声明一些在使用 new
调用时将 return 为正确类型的东西。即下面的export var FileSystemObject: { new (): FileSystemObject };
:
declare module Scripting {
export interface FileSystemObject {
GetExtensionName(path: string): string;
GetParentFolderName(path: string): string;
}
export var FileSystemObject: { new (): FileSystemObject };
}
var fso: Scripting.FileSystemObject = new Scripting.FileSystemObject();
var ext = fso.GetExtensionName('C:\test.txt'); //ext is recognized as a string
var badResult = fso.NonExistentMethod(); //will not compile
UPDATE 要自己实现类似的功能,您可以这样做:
module Scripting {
export interface FileSystemObject {
GetExtensionName(path: string): string;
GetParentFolderName(path: string): string;
}
export var FileSystemObject: { new (): FileSystemObject } = <any>function(){
return new ActiveXObject('Scripting.FileSystemObject');
};
}
var fso: Scripting.FileSystemObject = new Scripting.FileSystemObject();
var ext = fso.GetExtensionName('C:\test.txt'); //ext is recognized as a string
var badResult = fso.NonExistentMethod(); //will not compile