英文:
Typescript misunderstanding with ElasticSearch Node Client
问题
使用:
- NodeJS
v16.16.0
- "@elastic/elasticsearch": "8.7.0"
我想创建一个可以接受多种批量操作的函数。我的目标是确保该函数的输入将对我的索引产生良好的值(这里是 a
或 b
)。
以下是我无法正确输入的代码片段:
import { Client } from "@elastic/elasticsearch";
// 操作 1 影响一个使用 "index" 操作的索引
interface Op1IndexRow {
index: {
_index: string;
_id: string;
retry_on_conflict: number;
}
}
interface Op1BulkDocument {
a: string,
}
type Op1BulkBody = Array<Op1BulkDocument | Op1IndexRow>;
interface Op2IndexRow {
index: {
_index: string;
_id: string;
retry_on_conflict: number;
}
}
interface Op2BulkDocument {
b: string,
}
type Op2BulkBody = Array<Op2BulkDocument | Op2IndexRow>;
const client = new Client({
node: 'localhost'
})
const bulkSave = async (operations: Op1BulkBody | Op2BulkBody) => {
await client.bulk({
refresh: true,
operations,
});
}
我真正不理解的是,我可以通过以下类型使其“typescript友好”:Array<Op1BulkDocument | Op1IndexRow | Op2BulkDocument | Op2IndexRow>
。
问题是,这个类型对我来说是错误的,因为操作要么是 Op1BulkDocument | Op1IndexRow
,要么是 Op2BulkDocument | Op2IndexRow
,但从不同时。
英文:
Using:
- NodeJS
v16.16.0
- "@elastic/elasticsearch": "8.7.0",
I want to create a function that will accept multiple kind of bulk operations.
The goal for me is to ensure the input of this functions will affect my index with good values (here a
or b
).
Here is the code snippet that i cannot correctly type:
import { Client } from "@elastic/elasticsearch";
// Operation 1 affect 1 index with "index" action
interface Op1IndexRow {
index: {
_index: string;
_id: string;
retry_on_conflict: number;
}
}
interface Op1BulkDocument {
a: string,
}
type Op1BulkBody = Array<Op1BulkDocument | Op1IndexRow>;
interface Op2IndexRow {
index: {
_index: string;
_id: string;
retry_on_conflict: number;
}
}
interface Op2BulkDocument {
b: string,
}
type Op2BulkBody = Array<Op2BulkDocument | Op2IndexRow>;
const client = new Client({
node: 'localhost'
})
const bulkSave = async (operations: Op1BulkBody | Op2BulkBody) => {
await client.bulk({
refresh: true,
operations,
});
}
The thing I really don't understand is that i can make it "typescript friendly" with the following type: Array<Op1BulkDocument | Op1IndexRow | Op2BulkDocument | Op2IndexRow>
.
The problem is that this type is wrong for me because the operations is either Op1BulkDocument | Op1IndexRow
either Op2BulkDocument | Op2IndexRow
but never both at the same time.
答案1
得分: 0
提供的代码几乎实现了你想要的。例如,它不允许你混合使用 Op1BulkDocument
和 Op2BulkDocument
:
declare const op1doc: Op1BulkDocument;
declare const op2doc: Op2BulkDocument;
bulkSave([op1doc, op2doc]);
> 类型“(Op1BulkDocument | Op2BulkDocument)[]”的参数不能赋给类型“Op1BulkBody | Op2BulkBody”的参数。
这是因为 Op1BulkDocument
具有 a
成员,而 Op2BulkDocument
没有。
然而,它允许你混合使用 Op1IndexRow
和 Op2IndexRow
:
declare const op1index: Op1IndexRow;
declare const op2index: Op2IndexRow;
bulkSave([op1index, op2index]);
为什么呢?错误消息已经给出了提示:Op1IndexRow
和 Op2IndexRow
具有相同的定义。你可以将类型为 Op1IndexRow
的变量分配给类型为 Op2IndexRow
的变量,因为它们具有兼容的定义。
TypeScript 不仅仅关注精确的接口名称,而是检查接口定义是否兼容(是否可以 赋值)。
我建议你使用一个单一的接口 OpIndexRow
而不是两个不同但相同的接口。
英文:
The code you provided almost does what you want. For example, it does not allow you to mix Op1BulkDocument
with Op2BulkDocument
:
declare const op1doc: Op1BulkDocument;
declare const op2doc: Op2BulkDocument;
bulkSave([op1doc, op2doc]);
> Argument of type '(Op1BulkDocument | Op2BulkDocument)[]' is not assignable to parameter of type 'Op1BulkBody | Op2BulkBody'.
That is because Op1BulkDocument
has a member a
which Op2BulkDocument
does not have.
However it does allow you to mix Op1IndexRow
with Op2IndexRow
:
declare const op1index: Op1IndexRow;
declare const op2index: Op2IndexRow;
bulkSave([op1index, op2index]);
Why? The error message already gives you a hint: Op1IndexRow
en Op2IndexRow
have the same definition. You can assign a variable of type Op1IndexRow
to a variable op type Op2IndexRow
, because they have the compatible definitions.
TypeScript does not look at the exact interface name but checks if the interface definition is the compatible (is assignable).
I suggest you use a single interface OpIndexRow
instead of two different (but the same) interfaces.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论