我刚写了这个函数:
const cloneUrl = <T extends (URL | undefined)>(url: T): T => url instanceof URL
? new URL(url.toString())
: undefined;
但是,这有错误(或者至少是非常接近此的错误):
“未定义的'URL”不能分配到键入“T”。可以用任意类型实例化'T‘,该类型可能与'URL \ undefined’无关。 “未定义”类型不能指定为“T”。“未定义”可分配到“T”类型的约束,但“T”可以用另一种约束子类型“URL未定义”实例化。
很明显,我并没有掌握TypeScript的一些基本知识.
我的目标是这样,当用已知为URL的类型调用cloneUrl
时,返回类型是URL,但是当用URL | undefined
类型调用cloneUrl
时,返回类型是URL | undefined
。
示例:
class UrlWrapper {
private readonly _urlOne: URL
private readonly _urlTwo?: URL
constructor(urlOne: URL, urlTwo?: URL) {
this._urlOne = urlOne;
this._urlTwo = urlTwo;
}
get urlOne(): URL { return cloneUrl(this._urlOne); }
get urlTwo(): URL | undefined { return cloneUrl(this._urlTwo); }
}
看到urlWrapper.urlOne
如何总是一个不可定义的值,但是urlTwo
可以吗?
我尝试过不同类型的约束:
<T extends URL>
<T extends URL ? URL : undefined>
我尝试过不同的参数:
url?: T
url: T | undefined
我试着预测结果:
undefined as undefined
undefined as T | undefined
我尝试过将私有字段设置为可选字段,或者更改其类型。
我尝试使用类型检查函数:
const checkIsUrl = (url: unknown): url is URL => url instanceof URL;
...and更多。
但是关于TypeScript是如何看待那些我没有正确的心理模型的类型的,所以我就是没有得到它。
发布于 2020-08-21 15:50:37
我最近处理了这个问题,发现下面的内容似乎可以使用泛型和条件返回类型一起使用。any
使用的丑陋之处在于,但我不知道如何避免这种情况。这是巫毒,我不完全摸索,但类型是推断出你所期望的。
export function cloneUrl<T extends URL | undefined>(value: T): T extends URL ? URL : undefined {
return value instanceof URL ? new URL(value.toString()) : (undefined as any);
}
let source: URL | undefined = new URL("test");
cloneUrl(source); // URL
source = undefined;
cloneUrl(source); // undefined
let optionalSource: URL | undefined;
cloneUrl(optionalSource); // URL or undefined
cloneUrl(new Date()); // Nope: Date isn't a URL
https://stackoverflow.com/questions/63531189
复制相似问题