我有这段代码可以对结果类型进行建模。故障类型将包含所有可能的故障。 “不正确”不是其中之一,但我仍然可以将“不正确”返回为失败。
type Try<T, E> = Success<T> | Failures<E> | E;
// User code
type Failure = FileNotFound | NameNotFound;
class FileNotFound extends BaseFailure {}
class NameNotFound extends BaseFailure {}
class Incorrect extends BaseFailure {}
type Result<T> = Try<T, Failure>
function y() {
let x1 = x(1);
if (x1.isSuccess) {
} else {
x1.hasMany;
}
}
function x(a:number): Result<String> {
if (a>3) {
return new Success("Hallo");
} else {
return new Incorrect();
}
}
答案 0 :(得分:1)
Typescript使用结构兼容性来确定类型兼容性。因此,当确定类Incorrect
是否与Failure
兼容时,就将Incorrect
的结构与Failure
并集的成员进行比较。这样做会发现FileNotFound
与Incorrect
具有相同的结构,因此是兼容的。
要解决此问题,您可以将一个成员(最好是private
)添加到联合中的所有类。例如,这将失败:
class Success<T> { constructor(public value: T) { } isSuccess: true = true }
type Try<T, E> = Success<T> | E;
class BaseFailure {
isSuccess: false
}
type Failure = FileNotFound | NameNotFound;
class FileNotFound extends BaseFailure { private _type: "filenotfound" }
class NameNotFound extends BaseFailure { private _type: "namenotfound" }
class Incorrect extends BaseFailure { }
type Result<T> = Try<T, Failure>
function y() {
let x1 = x(1);
if (x1.isSuccess) {
} else {
}
}
function x(a: number): Result<String> {
if (a > 3) {
return new Success("Hallo");
} else {
return new Incorrect(); // error now
}
}
您还可以在BaseFailure
中包含私有字段,以强制实施者指定它:
class BaseFailure<T> {
isSuccess: false
private __type: T
}
class FileNotFound extends BaseFailure<"filenotfound"> { }
class NameNotFound extends BaseFailure<"namenotfound"> { }
class Incorrect extends BaseFailure<"incorrect"> { }
长期以来,已经讨论了允许一些名义上的键入(请参阅issue),但是目前这是我们所能做的最好的事情