通过以下方法:
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[]
。
如何以一种干净的方式实现这一目标?
答案 0 :(得分:2)
这里的问题是,尽管打字稿具有type guards,但它不能仅基于类型来推理类型内部的属性。您需要稍微“帮助”打字稿,以了解如果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
放在一些utils文件中,处理不同的api非常方便。