参数已根据未定义进行检查,但编译器仍会发出有关 TS2532 的警告
Parameter is checked against undefined but compiler still warns about TS2532
我在一个项目中使用 DynamoDb 从中获取数据。
我们的一个查询使用 :id
参数来过滤记录:
async getJobsFromDatabaseById(id: string): Promise<Job[]> {
const idParameter = ":id";
const parameters: AWS.DynamoDB.DocumentClient.QueryInput = {
//It has been already initialized inside ctor
/* eslint-disable @typescript-eslint/no-non-null-assertion */
TableName: this.tableName!,
KeyConditionExpression: `Id = ${idParameter}`
};
parameters.ExpressionAttributeValues = {};
parameters.ExpressionAttributeValues[idParameter] = id;
const result = await this.client().query(parameters).promise();
return this.mapDbRecordsToJobs(result.Items);
}
client()
方法 returns 与 AWS.DynamoDB.DocumentClient
实例。
在单元测试中,我通过以下方式模拟查询:
- 在安排阶段,我调用模拟逻辑并提供一个数组。其中的项目代表存储在数据库中的那些记录(
MockQuery([waitingJob, runningJob, failedJob]);
)。
- 发出查询后,在模拟中我使用
:id
参数来过滤返回数据。
import * as AWSMock from "jest-aws-sdk-mock";
...
//This type alias is introduced to avoid the usage of `Object`
/* eslint-disable @typescript-eslint/no-unused-vars*/
type DatabaseRecord = Record<string, unknown>;
...
const idParameter = ":id"; //I know this is tight-coupling to implementation
const MockQuery = (records: Array<DatabaseRecord>): void => {
AWSMock.mock(
"DynamoDB.DocumentClient",
"query",
(
_parameters: AWS.DynamoDB.DocumentClient.QueryInput,
callback: (
error: AWS.AWSError | undefined,
data: AWS.DynamoDB.DocumentClient.QueryOutput
) => void
) => {
let filteredRecords: DatabaseRecord[] = records;
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
/* eslint-disable @typescript-eslint/no-non-null-assertion */
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues![idParameter]
);
}
const output: AWS.DynamoDB.DocumentClient.QueryOutput = {
Items: filteredRecords
};
callback(undefined, output);
}
);
};
我的问题是我必须使用非空断言运算符,即使我根据 undefined
.
检查了对象
这很好用:
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
/* eslint-disable @typescript-eslint/no-non-null-assertion */
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues![idParameter]
);
}
但这给了我 TS2532 错误:对象可能是 undefined
:
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues[idParameter]
);
}
我尝试在不依赖 DynamoDb 的情况下重现同样的问题:
interface Test {
Parameters? : {[key: string]: any}
}
function GetData() : Test {
return {
Parameters: {
"x": 1,
"y": 2
}
};
}
function PrintData(data: Test){
if(data.Parameters)
{
console.log(data.Parameters["x"])
}
}
var data = GetData();
PrintData(data);
它确实可以正常工作。
我必须更改什么才能避免使用非空断言运算符?
即使可选链接不会引发 eslint 警告,它仍然感觉很奇怪:
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues?.[idParameter]
);
}
我们最终使用了这样的可选链接:
const idParamValue = _parameters.ExpressionAttributeValues?.[idParameter];
if (idParamValue) {
filteredRecords = records.filter(record => record.Id === idParamValue);
}
我在一个项目中使用 DynamoDb 从中获取数据。
我们的一个查询使用 :id
参数来过滤记录:
async getJobsFromDatabaseById(id: string): Promise<Job[]> {
const idParameter = ":id";
const parameters: AWS.DynamoDB.DocumentClient.QueryInput = {
//It has been already initialized inside ctor
/* eslint-disable @typescript-eslint/no-non-null-assertion */
TableName: this.tableName!,
KeyConditionExpression: `Id = ${idParameter}`
};
parameters.ExpressionAttributeValues = {};
parameters.ExpressionAttributeValues[idParameter] = id;
const result = await this.client().query(parameters).promise();
return this.mapDbRecordsToJobs(result.Items);
}
client()
方法 returns 与 AWS.DynamoDB.DocumentClient
实例。
在单元测试中,我通过以下方式模拟查询:
- 在安排阶段,我调用模拟逻辑并提供一个数组。其中的项目代表存储在数据库中的那些记录(
MockQuery([waitingJob, runningJob, failedJob]);
)。 - 发出查询后,在模拟中我使用
:id
参数来过滤返回数据。
import * as AWSMock from "jest-aws-sdk-mock";
...
//This type alias is introduced to avoid the usage of `Object`
/* eslint-disable @typescript-eslint/no-unused-vars*/
type DatabaseRecord = Record<string, unknown>;
...
const idParameter = ":id"; //I know this is tight-coupling to implementation
const MockQuery = (records: Array<DatabaseRecord>): void => {
AWSMock.mock(
"DynamoDB.DocumentClient",
"query",
(
_parameters: AWS.DynamoDB.DocumentClient.QueryInput,
callback: (
error: AWS.AWSError | undefined,
data: AWS.DynamoDB.DocumentClient.QueryOutput
) => void
) => {
let filteredRecords: DatabaseRecord[] = records;
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
/* eslint-disable @typescript-eslint/no-non-null-assertion */
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues![idParameter]
);
}
const output: AWS.DynamoDB.DocumentClient.QueryOutput = {
Items: filteredRecords
};
callback(undefined, output);
}
);
};
我的问题是我必须使用非空断言运算符,即使我根据 undefined
.
检查了对象
这很好用:
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
/* eslint-disable @typescript-eslint/no-non-null-assertion */
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues![idParameter]
);
}
但这给了我 TS2532 错误:对象可能是 undefined
:
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues[idParameter]
);
}
我尝试在不依赖 DynamoDb 的情况下重现同样的问题:
interface Test {
Parameters? : {[key: string]: any}
}
function GetData() : Test {
return {
Parameters: {
"x": 1,
"y": 2
}
};
}
function PrintData(data: Test){
if(data.Parameters)
{
console.log(data.Parameters["x"])
}
}
var data = GetData();
PrintData(data);
它确实可以正常工作。
我必须更改什么才能避免使用非空断言运算符?
即使可选链接不会引发 eslint 警告,它仍然感觉很奇怪:
if (
_parameters.ExpressionAttributeValues &&
_parameters.ExpressionAttributeValues[idParameter]
) {
filteredRecords = records.filter(
record => record.Id === _parameters.ExpressionAttributeValues?.[idParameter]
);
}
我们最终使用了这样的可选链接:
const idParamValue = _parameters.ExpressionAttributeValues?.[idParameter];
if (idParamValue) {
filteredRecords = records.filter(record => record.Id === idParamValue);
}