英文:
Typescript - Ensure that id is present in array
问题 {#heading}
以下是您要翻译的内容:
我有一个商店,我想要正确管理 id。假设我有以下的 Posts 商店:
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>; }; </code></pre> <p>如果选择了一篇文章,postId 就会设置为所选文章的 id。我想告诉 TypeScript postId 始终/应始终在 posts 中。这样我就可以确保如果我想找到正确的文章,它总是存在。</p> <p>在 TypeScript 中是否有办法做到这一点?</p> <p>类似于这样:</p> <pre><code>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&amp;lt;Post, &amp;quot;id&amp;quot;&amp;gt;) =&amp;gt; Promise&amp;lt;void&amp;gt;; updatePost: (id: number, post: Partial&amp;lt;Post&amp;gt;) =&amp;gt; Promise&amp;lt;void&amp;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&amp;lt;&amp;quot;id&amp;quot;&amp;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>&lt;<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>&gt;) <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">void</span>&gt;; </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>&lt;<span style="color:#f92672">Post</span>&gt;) <span style="color:#f92672">=&gt;</span> <span style="color:#a6e22e">Promise</span>&lt;<span style="color:#f92672">void</span>&gt;; </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: &amp;quot;Post 5&amp;quot;, body: &amp;quot;some description&amp;quot; }, { id: 42069, title: &amp;quot;Post 42069&amp;quot;, body: &amp;quot;some description&amp;quot; }, { id: 666, title: &amp;quot;Post 666&amp;quot;, body: &amp;quot;some description&amp;quot; } ] as const; type Store = { postId: (typeof posts)[number][&amp;quot;id&amp;quot;]; // 3 | 42069 | 666 posts: Post[]; addPost: (post: Omit&amp;lt;Post, &amp;quot;id&amp;quot;&amp;gt;) =&amp;gt; Promise&amp;lt;void&amp;gt;; updatePost: (id: number, post: Partial&amp;lt;Post&amp;gt;) =&amp;gt; Promise&amp;lt;void&amp;gt;; }; </code></pre> </details> <p></p> </div>