如何为可以同时属性(不带参数)或方法(带参数)的成员建模?
可以从没有参数的Javascript调用WSH Enivronment属性:
var shell = new ActiveXObject('WScript.Shell');
var env = shell.Environment;
或者,作为带参数的属性,从Javascript看起来像一个方法调用:
var filteredEnv = shell.Environment('System');
两种情况都返回WshEnvironment的实例,这是一组环境变量。
但是,在作为没有任何参数的方法调用时会引发错误:
var env2 = shell.Environment();
我可以将它建模为属性,或者作为带参数的方法,但不能同时建模:
declare interface WshShell {
// ...
// Error: Duplicate identifier
Environment: WshEnvironment;
Environment(Type: 'System' | 'User' | 'Process' | 'Volatile'): WshEnvironment;
// ...
}
我可以输入WshEnvironment & {(Type: 'System' | 'User' | 'Process' | 'Volatile'): WshEnvironment}
;然后将编译以下内容:
let x: WshShell;
console.log(x.Environment.Count);
console.log(x.Environment('Process').Count);
但是Typescript会推断出从x.Environment
返回的对象上的调用签名来过滤值,而调用签名实际上返回一个值,其中参数作为变量名称:
let env = x.Environment;
// Typescript will type filteredEnv as WshEnvironment
// At runtime, filteredEnv will contain an empty string (unless there is an environment variable named 'Process')
let filteredEnv = env('Process');
答案 0 :(得分:1)
您可以声明具有扩展WshEnvironment
// Added for testing
declare interface WshEnvironment{
(name: 'OS'): string
}
declare interface WshEnvironmentWithInvoke extends WshEnvironment {
(Type: 'System' | 'User' | 'Proces' | 'Volatile'): WshEnvironment;
}
declare interface WshShell {
Environment: WshEnvironmentWithInvoke;
}
let shell: WshShell;
shell.Environment("System")("OS");
shell.Environment("OS");
修改强>
上述解决方案允许进行这样的调用:
let env = x.Environment;
let filteredEnv = env('System');
不幸的是,在Typescript中无法正确输入,基本上有一个属性在从对象中分配出来时会丢失一些属性。我会去优化常见的场景,这里似乎是你指定参数的版本,主要是因为文档中的这一行:
如果未提供strType,则Environment属性将根据操作系统返回不同的环境变量类型。
我会创建一个辅助函数来为演员提供一些上下文,而不是内联:
declare interface WshEnvironment{
(name: 'OS'): string
}
declare interface WshShell {
Environment (Type?: 'System' | 'User' | 'Proces' | 'Volatile'): WshEnvironment
}
function defaultEnvironment(shell: WshShell) :WshEnvironment {
return shell.Environment as any;
}
var shell: WshShell = new ActiveXObject('WScript.Shell');
var s = defaultEnvironment(shell);
WScript.Echo(s("OS"));
WScript.Echo(shell.Environment('System')("OS"));