TypeScript - 类型 'boolean' 不满足 returns 布尔值类型的约束
TypeScript - Type 'boolean' does not satisfy the constraint of a type that returns a boolean
我有一个管理对象缓存的 TypeScript class。它有一个接受项目 ID 的 get
方法,以及一个可选的布尔值,用于确定是否应调用 API 来获取尚未缓存的对象。如果布尔参数是 false
或 undefined
,该方法应该 return CachedObject | undefined
。否则,它应该 return Promise<CachedObject | undefined>
。但是,布尔参数只有在 Cache
class 的 FetchObject
类型参数为 true
:
时才可用
class ExampleClass {};
type CachedObject = ExampleClass;
type GetFetch<FetchObject> = FetchObject extends true ? boolean : false;
type Result<CachedObject, Fetch> = Fetch extends true ? Promise<CachedObject | undefined> : (CachedObject | undefined);
export default class Cache<FetchObject = true> {
get<Fetch extends GetFetch<FetchObject> = false>(id: string, fetch?: Fetch): Result<CachedObject, Fetch> {
//
return;
}
}
new Cache<false>().get("123"); // ExampleClass | undefined
new Cache().get("123"); // ExampleClass | undefined
new Cache().get("123", true); // Promise<ExampleClass | undefined>
然而,第 10 行(get<...>(...)
)对于 = false
默认类型参数有以下错误:
Type 'boolean' does not satisfy the constraint 'GetFetch<FetchObject>'
我发现如果 FetchObject
是在没有 class 的情况下明确定义的:
type FetchObject = true;
export default function get<Fetch extends GetFetch<FetchObject> = false>(id: string, fetch?: Fetch): Result<CachedObject, Fetch> {
//
return;
}
没有任何错误,get
函数可以正常使用。为什么这不能用作 class 的类型参数?
这个很棘手。我尽力解释发生了什么。除非必须(出于性能原因),否则 Typescript 不会完全评估泛型。 GetFetch<FetchObject>
只包含可以是任何东西的泛型,所以编译器还没有评估。如果您已经像使用 type FetchObject = true;
那样输入了一些真实类型,这将有所不同。当您想将 Fetch
的默认值设置为 false
时,问题就出现了。因为 GetFetch<FetchObject>
还没有完全计算,编译器不知道表达式 FetchObject extends true ? boolean : false;
只能是布尔值。无论编译器认为 GetFetch<FetchObject>
的计算结果是什么,我们都可以肯定它不是 boolean
。这个问题的解决方案是要么强制编译器相信表达式只能是布尔值,要么将表达式移动到必须对其进行全面评估的位置。我认为解决此问题的最佳方法是将评估移至函数结果,如 this:
class ExampleClass {};
type CachedObject = ExampleClass;
type Result<CachedObject, Fetch> = Fetch extends true ? Promise<CachedObject | undefined> : (CachedObject | undefined);
// prevent fetching, FetchObject= true
type CanBeFetched<FetchedObject, Fetch> = FetchedObject extends true ? Fetch : never;
export default class Cache<FetchObject = true> {
get<Fetch extends boolean = false>(id: string, fetch?: CanBeFetched<FetchObject, Fetch>): Result<CachedObject, Fetch> {
// do something
return null as any;
}
}
new Cache<false>().get("123"); // ExampleClass | undefined
new Cache<false>().get("123", true); // Error, can't be used when FetchObject = false.
new Cache().get("123"); // ExampleClass | undefined
new Cache().get("123", true); // Promise<ExampleClass | undefined>
new Cache().get("123", false); // ExampleClass | undefined
我有一个管理对象缓存的 TypeScript class。它有一个接受项目 ID 的 get
方法,以及一个可选的布尔值,用于确定是否应调用 API 来获取尚未缓存的对象。如果布尔参数是 false
或 undefined
,该方法应该 return CachedObject | undefined
。否则,它应该 return Promise<CachedObject | undefined>
。但是,布尔参数只有在 Cache
class 的 FetchObject
类型参数为 true
:
class ExampleClass {};
type CachedObject = ExampleClass;
type GetFetch<FetchObject> = FetchObject extends true ? boolean : false;
type Result<CachedObject, Fetch> = Fetch extends true ? Promise<CachedObject | undefined> : (CachedObject | undefined);
export default class Cache<FetchObject = true> {
get<Fetch extends GetFetch<FetchObject> = false>(id: string, fetch?: Fetch): Result<CachedObject, Fetch> {
//
return;
}
}
new Cache<false>().get("123"); // ExampleClass | undefined
new Cache().get("123"); // ExampleClass | undefined
new Cache().get("123", true); // Promise<ExampleClass | undefined>
然而,第 10 行(get<...>(...)
)对于 = false
默认类型参数有以下错误:
Type 'boolean' does not satisfy the constraint 'GetFetch<FetchObject>'
我发现如果 FetchObject
是在没有 class 的情况下明确定义的:
type FetchObject = true;
export default function get<Fetch extends GetFetch<FetchObject> = false>(id: string, fetch?: Fetch): Result<CachedObject, Fetch> {
//
return;
}
没有任何错误,get
函数可以正常使用。为什么这不能用作 class 的类型参数?
这个很棘手。我尽力解释发生了什么。除非必须(出于性能原因),否则 Typescript 不会完全评估泛型。 GetFetch<FetchObject>
只包含可以是任何东西的泛型,所以编译器还没有评估。如果您已经像使用 type FetchObject = true;
那样输入了一些真实类型,这将有所不同。当您想将 Fetch
的默认值设置为 false
时,问题就出现了。因为 GetFetch<FetchObject>
还没有完全计算,编译器不知道表达式 FetchObject extends true ? boolean : false;
只能是布尔值。无论编译器认为 GetFetch<FetchObject>
的计算结果是什么,我们都可以肯定它不是 boolean
。这个问题的解决方案是要么强制编译器相信表达式只能是布尔值,要么将表达式移动到必须对其进行全面评估的位置。我认为解决此问题的最佳方法是将评估移至函数结果,如 this:
class ExampleClass {};
type CachedObject = ExampleClass;
type Result<CachedObject, Fetch> = Fetch extends true ? Promise<CachedObject | undefined> : (CachedObject | undefined);
// prevent fetching, FetchObject= true
type CanBeFetched<FetchedObject, Fetch> = FetchedObject extends true ? Fetch : never;
export default class Cache<FetchObject = true> {
get<Fetch extends boolean = false>(id: string, fetch?: CanBeFetched<FetchObject, Fetch>): Result<CachedObject, Fetch> {
// do something
return null as any;
}
}
new Cache<false>().get("123"); // ExampleClass | undefined
new Cache<false>().get("123", true); // Error, can't be used when FetchObject = false.
new Cache().get("123"); // ExampleClass | undefined
new Cache().get("123", true); // Promise<ExampleClass | undefined>
new Cache().get("123", false); // ExampleClass | undefined