英文:
Typescript - Ensure that id is present in array
问题 {#heading}
以下是您要翻译的内容:
我有一个商店,我想要正确管理 id。假设我有以下的 Posts 商店:
```typescript
type Post = {
id: number;
title: string;
body?: string;
}
type Store = {
postId: number | null;
posts: Post[];
addPost: (post: Omit<Post, "id">) => Promise<void>;
updatePost: (id: number, post: Partial<Post>) => Promise<void>;
};
如果选择了一篇文章,postId 就会设置为所选文章的 id。我想告诉 TypeScript postId 始终/应始终在 posts 中。这样我就可以确保如果我想找到正确的文章,它总是存在。
在 TypeScript 中是否有办法做到这一点?
类似于这样:
type Store = {
postId: (number in StoreType.posts.key<"id">) | null;
posts: Post[];
// ...
};
<details>
<summary>英文:</summary>
I have a Store in which I want to manage ids properly. Say I have the following Posts Store:
```typescript
type Post = {
id: number;
title: string;
body?: string;
}
type Store = {
postId: number | null;
posts: Post[];
addPost: (post: Omit&lt;Post, &quot;id&quot;&gt;) =&gt; Promise&lt;void&gt;;
updatePost: (id: number, post: Partial&lt;Post&gt;) =&gt; Promise&lt;void&gt;;
};
</code></pre>
<p>If a post is selected, the postId is set to the selected post id. I want to tell typescript that this postId is always / should always be in posts. So I can be sure that if I want to find the proper post, it's always there.</p>
<p>Is there any way in typescript to do this?</p>
<p>Something like this:</p>
<pre><code>type Store = {
postId: (number in StoreType.posts.key&lt;&quot;id&quot;&gt;) | null;
posts: Post[];
// ...
};
</code></pre>
<h1 id="1">答案1</h1>
<p><strong>得分</strong>: 2</p>
<p>没有,无法实现这一点。</p>
<p>这取决于运行时动态,超出了TS检查的范围。TS无法确定当您设置<code>id</code>时,是否还有一个具有该id的数组项。</p>
<details>
<summary>英文:</summary>
<p>No, there is no way to achieve this.</p>
<p>This depends on runtime dynamics which are out of scope for TS to check. There is no way for TS to figure out that when you're setting the <code>id</code> you are also having an item in the array with that id.</p>
</details>
<h1 id="2">答案2</h1>
<p><strong>得分</strong>: 1</p>
<p>One thing you could do is define your posts <code>as const</code> so the compiler can infer the post ids at compiler time. However, it's not possible to do that kind of type checking at runtime.</p>
<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;"><code><span style="display:flex;"><span><span style="color:#66d9ef">const</span> <span style="color:#a6e22e">posts</span> <span style="color:#f92672">=</span> [
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">id</span>: <span style="color:#66d9ef">3</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"Post 5"</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">body</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"some description"</span>
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">id</span>: <span style="color:#66d9ef">42069</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"Post 42069"</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">body</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"some description"</span>
</span></span><span style="display:flex;"><span> },
</span></span><span style="display:flex;"><span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">id</span>: <span style="color:#66d9ef">666</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">title</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"Post 666"</span>,
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">body</span><span style="color:#f92672">:</span> <span style="color:#e6db74">"some description"</span>
</span></span><span style="display:flex;"><span> }
</span></span><span style="display:flex;"><span>] <span style="color:#66d9ef">as</span> <span style="color:#66d9ef">const</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Store</span> <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">postId</span><span style="color:#f92672">:</span> (<span style="color:#66d9ef">typeof</span> <span style="color:#a6e22e">posts</span>)[<span style="color:#66d9ef">number</span>][<span style="color:#e6db74">"id"</span>]; <span style="color:#75715e">// 3 | 42069 | 666
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span> <span style="color:#a6e22e">posts</span>: <span style="color:#66d9ef">Post</span>[];
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">addPost</span><span style="color:#f92672">:</span> (<span style="color:#a6e22e">post</span>: <span style="color:#66d9ef">Omit</span><<span style="color:#f92672">Post</span><span style="color:#960050;background-color:#1e0010">,</span> <span style="color:#960050;background-color:#1e0010">"</span><span style="color:#a6e22e">id</span><span style="color:#960050;background-color:#1e0010">"</span>>) <span style="color:#f92672">=></span> <span style="color:#a6e22e">Promise</span><<span style="color:#f92672">void</span>>;
</span></span><span style="display:flex;"><span> <span style="color:#a6e22e">updatePost</span><span style="color:#f92672">:</span> (<span style="color:#a6e22e">id</span>: <span style="color:#66d9ef">number</span>, <span style="color:#a6e22e">post</span>: <span style="color:#66d9ef">Partial</span><<span style="color:#f92672">Post</span>>) <span style="color:#f92672">=></span> <span style="color:#a6e22e">Promise</span><<span style="color:#f92672">void</span>>;
</span></span><span style="display:flex;"><span>};
</span></span></code></pre>
<details>
<summary>英文:</summary>
<p>One thing you could do is define your posts <code>as const</code> so the compiler can infer the post ids at compiler time. However, it's not possible to do that kind of type checking at runtime.</p>
<pre><code>const posts = [
{
id: 3,
title: &quot;Post 5&quot;,
body: &quot;some description&quot;
},
{
id: 42069,
title: &quot;Post 42069&quot;,
body: &quot;some description&quot;
},
{
id: 666,
title: &quot;Post 666&quot;,
body: &quot;some description&quot;
}
] as const;
type Store = {
postId: (typeof posts)[number][&quot;id&quot;]; // 3 | 42069 | 666
posts: Post[];
addPost: (post: Omit&lt;Post, &quot;id&quot;&gt;) =&gt; Promise&lt;void&gt;;
updatePost: (id: number, post: Partial&lt;Post&gt;) =&gt; Promise&lt;void&gt;;
};
</code></pre>
</details>
<p></p>
</div>
```