采用以下方法:
private async getJobExecutionIds(): Promise<Athena.ListQueryExecutionsOutput> {
const params = { NextToken: this.nextToken, MaxResults: 50 };
const response = await this.athena.listQueryExecutions(params).promise();
if (response.QueryExecutionIds instanceof Array) {
return response;
}
throw new Error("No Athena QueryExecutionIds");
}
我添加了response.QueryExecutionIds instanceof Array
检查,以保证我的用户安全地依赖于QueryExecutionIds: string[] | undefined
的存在
但是,当我使用此方法时:
const executionIds = await this.getJobExecutionIds();
我仍然不能依靠executionIds.QueryExecutionIds
作为string[]
在那里。
我怎样才能以干净的方式实现这一目标?
这里的问题是,虽然打字稿具有类型保护,但它不能推理类型中的属性,只能推理类型。你需要稍微"帮助"打字稿,才能理解如果response.QueryExecutionIds instanceof Array
,它实际上是一种全新的类型。
因此,第一步是基于原始类型定义此新类型。在此类型中,QueryExecutionIds
不能未定义。这里有两个选项,选择你最喜欢的:
type ListQueryExecutionsOutputSafe = Athena.ListQueryExecutionsOutput & {QueryExecutionIds: string[]}
interface ListQueryExecutionsOutputSafe extends Athena.ListQueryExecutionsOutput {
QueryExecutionIds: string[];
}
下一步是定义一些自定义类型保护:
const checkIfListQueryExecutionsOutputIsSafe = (obj: Athena.ListQueryExecutionsOutput): obj is ListQueryExecutionsOutputSafe =>
!!obj.QueryExecutionIds;
最后:
private async getJobExecutionIds(): Promise<ListQueryExecutionsOutputSafe> {
const params = {NextToken: this.nextToken, MaxResults: 50};
const response = await this.athena.listQueryExecutions(params).promise();
if (checkIfListQueryExecutionsOutputIsSafe(response)) {
return response;
}
throw new Error("No Athena QueryExecutionIds");
}
但为什么要止步于此呢?让我们让一切都变得通用:
type TypeWithNotNullProp<T, SafeKey extends keyof T> = T & {[K in SafeKey]-?: T[K]}
const checkSafeProp = <T, SafeKey extends keyof T>(obj: T, key: SafeKey): obj is TypeWithNotNullProp<T, SafeKey> =>
!!obj[key];
private async getJobExecutionIds(): Promise<ListQueryExecutionsOutputSafe> {
const params = {NextToken: this.nextToken, MaxResults: 50};
const response = await this.athena.listQueryExecutions(params).promise();
if (checkSafeProp(response, 'QueryExecutionIds')) {
return response;
}
throw new Error("No Athena QueryExecutionIds");
}
我通常把TypeWithNotNullProp
和checkSafeProp
放在一些实用程序文件中,处理不同的 API 非常方便。