我有一个函数可以返回类型O
或O[]
:
public convert(data?: I | I[]) {
if (data) {
this.input(data);
}
if (!this._data) {
const e = new Error("You must first set the data before trying to convert!");
e.name = "NotReady";
throw e;
}
return Array.isArray(this._data)
? this._convertArray(this._data) as O
: this._convertObject(this._data) as O[];
}
返回类型取决于用户输入的数据:
public input(data: I | I[]) {
this._data = data;
return this;
}
总结:
I
; convert()
将返回类型为O
的输出I[]
; convert()
将返回类型为O[]
的输出最初,我认为返回convert
的条件语句就足够了,但这行不通。我猜我没有足够的创造力,但是我碰壁了。任何帮助将不胜感激。
答案 0 :(得分:0)
参考您的评论:“转换返回就足够了,但是那行不通。” 您看到棉绒错误还是在运行时出错?
我在下面列出了一些示例代码,这些代码返回正确的内容/类型并执行我认为您需要的操作。我至少做了两个提示类型的添加-也许这就是您的代码所需要的?
interface I {
id: number;
}
interface O {
guid: number;
}
class StackOverFlowQuestionClass {
_data: I | I[];
public convert(data?: I): O;
public convert(data?: I[]): O[];
public convert(data?: I | I[]): O | O[] {
if (data) {
this.input(data);
}
if (!this._data) {
const e = new Error(
"You must first set the data before trying to convert!"
);
e.name = "NotReady";
throw e;
}
return Array.isArray(this._data)
? (this._convertArray(this._data as I[]) as O[])
: (this._convertObject(this._data as I) as O);
}
public input(data: I | I[]) {
this._data = data;
return this;
}
public _convertArray(items: I[]): O[] {
return items.map(item => this._convertObject(item));
}
public _convertObject(item: I): O {
return { guid: item.id };
}
}
答案 1 :(得分:0)
似乎没有办法避免convert
的返回类型含糊不清,因此为了简化客户端调用,我以以下方式扩展了公共API:
public convertArray(data?: I[]) {
if(!data && !Array.isArray(this._data)) {
const e = new Error(`Using convertArray() requires that the input is also an array and it is of type ${typeof this._data}`);
e.name = "TypedMapper::InvalidFormat";
throw e;
}
return this.convert(data) as O[];
}
public convertObject(data?: I) {
if(!data && Array.isArray(this._data)) {
const e = new Error(`Using convertObject() requires that the input is an object and it is of type ${typeof this._data}`);
e.name = "TypedMapper::InvalidFormat";
throw e;
}
return this.convert(data) as O;
}
客户端仍然可以使用convert()
,但需要进行类型转换才能有效使用。相反,更方便的语法是:
const result = tm.convertObject(objInput); // typed to O
const result2 = tm.convertArray(arrInput); // typed to O[]
答案 2 :(得分:0)
从TypeScript 2.8开始,您可以使用conditional types
class Test<I, O> {
private _data!: I | I[];
convert<T extends I | I[]>(data?: T): T extends I[] ? O[] : O {
if (data) {
this.input(data);
}
if (!this._data) {
const e = new Error('You must first set the data before trying to convert!');
e.name = 'NotReady';
throw e;
}
// note the `as any` you can use a // @ts-ignore comment if you prefer
// @ts-ignore
return Array.isArray(this._data) ? (this._convertArray(this._data as I[]) as any) : (this._convertObject(this._data as I) as any);
}
private input(data: I | I[]): void {
// ...
}
private _convertArray(data: I[]): O[] {
// ...
}
private _convertObject(data: I): O {
// ...
}
}
const a: Test<string, number> = new Test();
const b = a.convert(''); // number
const c = a.convert(['']); // number[]