对于TS类型系统的各个方面来说仍然是新的。我收到一个'?' expected [1005]
错误。
使用TS 3.1.6版
我的tsconfig编译器选项:
"compilerOptions": {
"strict": true,
"module": "commonjs",
"outDir": "www/staging/js",
"rootDir": "src/",
"sourceMap": false,
"target": "es5",
"experimentalDecorators": true
},
导致该问题的代码是handler
参数类型注释(特别是在_convert
方法的右括号之前的位置(:
private _convert(
doc: any,
handler: keyof StringHelperService extends (str: string) => string
): any {
let converted = {} as {[str: string]: any}
for (let prop in doc) {
converted[handler(prop)] = doc[prop];
}
return converted;
}
注释应该说"StringHelperService的一个密钥,仅当它具有以下函数签名时"。这是StringHelperService:
export class StringHelperService {
public static $inject: ReadonlyArray<string> = [];
constructor() {
this.pascalToCamel = this.pascalToCamel.bind(this);
this.camelToPascal = this.camelToPascal.bind(this);
}
pascalToCamel(str: string): string {
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
camelToPascal(str: string): string {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
}
我已经解决了这个问题
以下是_convert
的实现者,以帮助解释该方法是如何使用的,以及它与StringHelperService
的关系。我为函数声明创建了一个接口:
export interface StringConverter {
(str: string): string;
}
通过使用这个接口代替helper
的原始注释,我解决了这个问题。问题是我最初的注释完全错误。我的谬论源于误解,即我会使用key of
类型来注释类型T的成员的类型,而实际上这是我想要的METHOD。不知道我为什么要这么跳。
export class PropertyNameConverterService {
public static $inject: ReadonlyArray<string> = ['stringHelper'];
constructor(private stringHelper: StringHelperService) {
this._convert = this._convert.bind(this);
this.pascalToCamel = this.pascalToCamel.bind(this);
this.camelToPascal = this.camelToPascal.bind(this);
}
private _convert(
doc: any,
handler: StringConverter
): any {
let converted = {} as {[str: string]: any}
for (let prop in doc) {
converted[handler(prop)] = doc[prop];
}
return converted;
}
pascalToCamel(doc: any): any {
return this._convert(doc, this.stringHelper.pascalToCamel);
}
camelToPascal(doc: any): any {
return this._convert(doc, this.stringHelper.camelToPascal);
}
}
注释应该说"StringHelperService的一个键,只有当它具有以下函数签名时"。
这就是你所说的你希望注释做的。
type KeysWithThisSignature<T, U> = {
[P in keyof T]: T[P] extends U ? P : never;
}[keyof T]
// type Keys = "pascalToCamel" | "camelToPascal"
type Keys = KeysWithThisSignature<StringHelperService, (str: string) => string>;
不过,您给出的示例是一个不同的用例。在本例中,handler
不是string
,而是具有特定签名的函数。
pascalToCamel(doc: any): any {
// the second argument is a function not a string
return this._convert(doc, this.stringHelper.pascalToCamel);
}
在这种情况下,您似乎真正想要的_convert
是:
private _convert(doc: any, handler: (str: string) => string): any {
// ...
}