<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Node.js ‣ てんハロ｜未経験エンジニアのIT学習ログ</title>
	<atom:link href="https://it-bokenki.com/category/node-js/feed/" rel="self" type="application/rss+xml" />
	<link>https://it-bokenki.com</link>
	<description>Hello Worldから、今日も生きてる</description>
	<lastBuildDate>Fri, 11 Jul 2025 04:53:13 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://it-bokenki.com/wp-content/uploads/2025/06/cropped-ブログ　アイコン-32x32.png</url>
	<title>Node.js ‣ てんハロ｜未経験エンジニアのIT学習ログ</title>
	<link>https://it-bokenki.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Zodの .object() とセットで使うバリデーション構文まとめ</title>
		<link>https://it-bokenki.com/2025/06/16/zod-object-validation/</link>
					<comments>https://it-bokenki.com/2025/06/16/zod-object-validation/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Mon, 16 Jun 2025 03:57:31 +0000</pubDate>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[React]]></category>
		<category><![CDATA[TypeScript]]></category>
		<category><![CDATA[フロントエンド]]></category>
		<category><![CDATA[Zod]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3373</guid>

					<description><![CDATA[<p>でじぼうです。 Zodを使ったバリデーションで一番よく出てくるのが .object()でも実際の現場では、それだけでは足りないことが多いです。 この記事では .object() と一緒によく使う構文だけにしぼって、未経験 [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/16/zod-object-validation/">Zodの .object() とセットで使うバリデーション構文まとめ</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>Zodを使ったバリデーションで一番よく出てくるのが <code>.object()</code><br>でも実際の現場では、それ<strong>だけでは足りないことが多い</strong>です。</p>



<p>この記事では <code>.object()</code> と一緒に<strong>よく使う構文だけ</strong>にしぼって、未経験でもわかるように解説します！</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！<br></p>



<ul class="wp-block-list">
<li style="font-size:15px">Zodってなに？</li>



<li style="font-size:15px">.object() ってなに？</li>



<li style="font-size:15px">よく使われる構文の違いが知りたい</li>
</ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img fetchpriority="high" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/16/f12-network-tab/" title="【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-160x90.png 160w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで</div><div class="blogcard-snippet internal-blogcard-snippet">F12キーで開く「Networkタブ」の基本を初心者向けに解説。通信状況の確認、APIのエラー調査、画面が動かない原因の特定に役立つ見方を紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">Zodとは？</span></h2>



<p>Zodは、TypeScriptで「入力ルール（バリデーション）」を簡単に定義できるライブラリです。</p>



<ul class="wp-block-list">
<li>形式チェック（文字列・数値・メールなど）</li>



<li>必須・任意の設定</li>



<li>条件付きのチェック</li>
</ul>



<p>などが、<strong>読みやすい構文で書ける</strong>のが特徴です。<br>より詳細は下記のブログをご確認ください。</p>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/11/zod/" title="Zodとは？React Hook Formとの連携でバリデーション実装" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-1-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">Zodとは？React Hook Formとの連携でバリデーション実装</div><div class="blogcard-snippet internal-blogcard-snippet">TypeScriptで使えるバリデーションライブラリ「Zod」の基本と、React Hook Formとの連携方法を解説します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">.object()とは？</span></h2>



<p>フォーム全体の「入力ルール」をまとめて定義できる、Zodの土台です。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  name: z.string(),
  email: z.string().email(),
});</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">email</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>name</code> は文字列の入力が必要（必須）</li>



<li><code>email</code> はメール形式での入力が必要（必須）</li>
</ul>



<p>このように、<code>.object()</code> を使うことで<strong>複数の入力項目を1つのスキーマとしてまとめる</strong>ことができます。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">一緒によく使う構文一覧【目的別】</span></h2>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>構文</th><th>できること</th><th>使用頻度</th></tr></thead><tbody><tr><td><code><span class="marker">.superRefine()</span></code></td><td>複数項目をまとめてチェック</td><td>◎ よく使う</td></tr><tr><td><code><span class="marker">.partial()</span></code><br>（パーシャル）</td><td>全ての項目を「入力なしでもOK」に</td><td>◎ よく使う</td></tr><tr><td><code><span class="marker">.merge()</span></code></td><td>スキーマ同士を合体</td><td>○ 時々使う</td></tr><tr><td><code><span class="marker">.extend()</span></code></td><td>既存のスキーマに追加する</td><td>○ 時々使う</td></tr><tr><td><code><span class="marker">.pick()</span></code></td><td>一部の項目だけ取り出す</td><td>○ 時々使う</td></tr><tr><td><code><span class="marker">.omit()</span></code></td><td>一部の項目を除外する</td><td>○ 時々使う</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc4">.superRefine()とは？</span></h2>



<p>複数項目を「まとめてチェック」したいときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  password: z.string(),
  confirm: z.string(),
}).superRefine((data, ctx) => {
  if (data.password !== data.confirm) {
    ctx.addIssue({
      path: [&#8220;confirm&#8221;],
      message: &#8220;パスワードが一致しません&#8221;,
      code: z.ZodIssueCode.custom,
    });
  }
});</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">password</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">confirm</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">superRefine</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">ctx</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">password</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!==</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">data</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">confirm</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">ctx</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">addIssue</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">path</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">confirm</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">]</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">message</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">パスワードが一致しません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">code</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">ZodIssueCode</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">custom</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<p>&#x1f4d8; <code>data</code> とは？</p>



<ul class="wp-block-list">
<li><code>z.object({...})</code> に渡したすべての入力値（name, email など）が入っているオブジェクトのことを指す</li>



<li>React Hook Form の <code>getValues()</code> と同じ構造</li>
</ul>



<p>&#x1f4d8; <code>ctx.addIssue()</code> とは？</p>



<ul class="wp-block-list">
<li>条件に合致した場合に、「この項目にエラーがある」と Zod に伝える関数</li>



<li><code>path: ["confirm"]</code> と指定すれば、<code>confirm</code> にエラーメッセージが表示できる</li>



<li><code>code: z.ZodIssueCode.custom</code> は「独自ルールによるエラー」であることを示す<br></li>
</ul>



<p>&#x1f4d8;コード全体の意味</p>



<ul class="wp-block-list">
<li><code>.superRefine()</code> は、バリデーションの<strong>対象全体（objectの中身）にアクセスできる</strong>関数</li>



<li><code>password</code> と <code>confirm</code> が一致していなければ、<code>confirm</code> 項目にエラーを追加</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>パスワード確認</li>



<li>日付の前後関係</li>



<li>条件付き入力のバリデーション</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc5">.partial()とは？</span></h2>



<p>全部「任意入力」にするときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  title: z.string(),
  content: z.string(),
}).partial();</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">title</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">content</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">partial</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>title</code> も <code>content</code> も、<strong>未入力でもエラーにならない</strong></li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>入力フォームで、<strong>どれか1つだけ更新</strong>したいとき（プロフィール編集など）</li>



<li>一部だけ更新するような画面で、<strong>全項目が必須でないとき</strong></li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc6">.optional() でも同じ意味になる</span></h3>



<p>下記の記載は、上記の<code><code>.partial()</code></code>で定義した場合と、結果はまったく同じになります。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const schema = z.object({
  title: z.string().optional(),
  content: z.string().optional(),
});
</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">title</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">optional</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">content</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">optional</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span></code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc7">では .partial() を使うメリットは？</span></h3>



<ul class="wp-block-list">
<li>プロパティがたくさんあるときに <strong>1つずつ <code>.optional()</code> を書かなくて済む</strong></li>



<li>スキーマを再利用する際に、<strong>必須版と任意版を簡単に切り替えられる</strong></li>
</ul>



<p>&#x2705; <code>.optional()</code> を個別に書いてもOK<br>&#x2705; <code>.partial()</code> は <strong>全部を一括で optional にしたいとき</strong>に便利！</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc8">.merge()とは？</span></h2>



<p>共通ルールと追加ルールを「合体する」ときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const base = z.object({ id: z.string() });
const detail = z.object({ name: z.string() });

const schema = base.merge(detail);</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">base</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">detail</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">schema</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">base</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">merge</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">detail</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>id</code> と <code>name</code> の両方を含んだ1つのスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>IDだけで定義した共通スキーマに、画面ごとの入力項目（詳細）を足したいとき</li>



<li><strong>共通部分と画面ごとの違いを分けて管理</strong>したいとき（保守性アップ）</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc9">.extend()とは？</span></h2>



<p>既存のスキーマに追加するときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const user = z.object({ name: z.string() });
const extended = user.extend({ age: z.number() });</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">user</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">extended</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">user</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">extend</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">number</span><span style="color: #D8DEE9FF">() </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>user</code> に <code>age</code> を追加した新しいスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li><strong>もとのスキーマを壊さずに</strong>追加したいとき（再利用性アップ）</li>



<li>複数画面で <code>user</code> は共通だが、年齢が必要なのは一部だけ…という場面など</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc10">.pick()とは？</span></h2>



<p>必要な項目だけ「取り出す」ときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const full = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number(),
});

const nameOnly = full.pick({ name: true });</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">number</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nameOnly</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">pick</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>name</code> だけを含むスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>一覧画面などで、<strong>一部の情報だけ使いたいとき</strong></li>



<li>画面に表示するフィールドを限定したいとき</li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc11">.omit()とは？</span></h2>



<p>不要な項目だけ「除外する」ときに利用します。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>const full = z.object({
  name: z.string(),
  email: z.string(),
  age: z.number(),
});

const noEmail = full.omit({ email: true });</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">age</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">number</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">noEmail</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">full</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">omit</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">email</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>email</code> を除外したスキーマを作る</li>
</ul>



<p><span class="badge-yellow">よくある使い方</span></p>



<ul class="wp-block-list">
<li>セキュリティ上、<strong>特定の項目を外したいとき</strong>（たとえばパスワードなど）</li>



<li>APIレスポンスで<strong>不要な情報を含めたくないとき</strong></li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc12">補足：.refine() は .object() の中で「項目ごと」に使う</span></h2>



<p><code>.refine()</code> は<strong>単体の項目</strong>に対して使い、複数項目にまたがるときは <code>.superRefine()</code> を使います。</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>z.object({
  username: z.string().refine(val => val !== &#8220;admin&#8221;, {
    message: &#8220;admin は使えません&#8221;,
  }),
});</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">object</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">username</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">z</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">string</span><span style="color: #D8DEE9FF">()</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">refine</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">val</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">val</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!==</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">admin</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">message</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">admin は使えません</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p><span class="badge-green">コードの意味</span></p>



<ul class="wp-block-list">
<li><code>username</code> が &#8220;admin&#8221; だったらエラーになる、という<strong>1つの項目に対する条件</strong></li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-default">
<a href="https://it-bokenki.com/2025/06/16/f12-network-tab/" title="【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img decoding="async" width="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-8-160x90.png 160w" sizes="(max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">【初心者向け】Networkタブの使い方をやさしく解説｜APIの見方や通信トラブル対処まで</div><div class="blogcard-snippet internal-blogcard-snippet">F12キーで開く「Networkタブ」の基本を初心者向けに解説。通信状況の確認、APIのエラー調査、画面が動かない原因の特定に役立つ見方を紹介します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div><p>The post <a href="https://it-bokenki.com/2025/06/16/zod-object-validation/">Zodの .object() とセットで使うバリデーション構文まとめ</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/16/zod-object-validation/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SMTPとは？メール送信の仕組みと実装・エラー内容まとめ</title>
		<link>https://it-bokenki.com/2025/06/14/smtp/</link>
					<comments>https://it-bokenki.com/2025/06/14/smtp/#respond</comments>
		
		<dc:creator><![CDATA[てんハロ運営者]]></dc:creator>
		<pubDate>Sat, 14 Jun 2025 14:32:39 +0000</pubDate>
				<category><![CDATA[API]]></category>
		<category><![CDATA[IT基礎知識]]></category>
		<category><![CDATA[Node.js]]></category>
		<guid isPermaLink="false">https://it-bokenki.com/?p=3293</guid>

					<description><![CDATA[<p>でじぼうです。 開発をすると SMTP って言葉よく聞きますよね。実際よくわかっていない人、集まってください！ご説明します。 Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち SMTP [&#8230;]</p>
<p>The post <a href="https://it-bokenki.com/2025/06/14/smtp/">SMTPとは？メール送信の仕組みと実装・エラー内容まとめ</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></description>
										<content:encoded><![CDATA[<p>でじぼうです。</p>



<p>開発をすると<strong> <code>SMTP</code></strong> って言葉よく聞きますよね。<br>実際よくわかっていない人、集まってください！ご説明します。</p>



<div class="wp-block-cocoon-blocks-balloon-ex-box-1 speech-wrap sb-id-1 sbs-stn sbp-l sbis-cb cf block-box"><div class="speech-person"><figure class="speech-icon"><img decoding="async" src="https://it-bokenki.com/wp-content/uploads/2023/05/名称未設定のデザイン-1-1-150x150.png" alt="でじぼう" class="speech-icon-image"/></figure><div class="speech-name">でじぼう</div></div><div class="speech-balloon">
<p>この記事は下記の方がおすすめ！<br></p>



<ul class="wp-block-list">
<li style="font-size:15px">SMTPってなに？</li>



<li style="font-size:15px">どう実装するのかわからない</li>



<li style="font-size:15px">エラーが出ても解読できない</li>
</ul>
</div></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NZROH">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www27.a8.net/svt/bgt?aid=230528653907&#038;wid=001&#038;eno=01&#038;mid=s00000023513004030000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=3T911P+F006GI+51FE+NZROH" alt=""></div>



<p class="has-text-align-center"><a href="https://px.a8.net/svt/ejp?a8mat=3T911P+F006GI+51FE+NWRNM">Instagramフォロワー数9,500人を越える人気のもち・大福店 えにかいたもち</a></p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc1">SMTPとは？</span></h2>



<p>SMTP（Simple Mail Transfer Protocol）とは、<strong>メールを送るときに使われる通信ルール</strong>のことです。</p>



<p>「プロトコル」とは「決まりごと」という意味なので、SMTPは「メール送信用の決まりごと」と覚えるとシンプルです。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc2">SMTPはどんなときに使われる？</span></h2>



<p>Gmailなどでメールを送るとき、その裏側ではSMTPが働いて、「どこに」「誰が」「何を」送ったかを伝えています。</p>



<p>例えるなら、SMTPは「郵便局の配達員」のような存在です。<br><strong>書いた手紙（メール）を相手の住所（メールアドレス）に届けてくれる役割</strong>です。</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc3">メール送信の流れ</span></h2>



<figure class="wp-block-image aligncenter size-full is-resized"><img loading="lazy" decoding="async" width="512" height="678" src="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-23.24.07.png" alt="SMTPとは？メール送信の仕組みと実装・エラー内容まとめ" class="wp-image-3358" style="width:360px;height:auto" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-23.24.07.png 512w, https://it-bokenki.com/wp-content/uploads/2025/06/スクリーンショット-2025-06-14-23.24.07-227x300.png 227w" sizes="auto, (max-width: 512px) 100vw, 512px" /></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc4">SMTPでよく出る用語と設定項目</span></h2>



<p>下記に、SMTP関連でよく利用する用語をまとめました。</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>用語</th><th>意味</th></tr></thead><tbody><tr><td>SMTPサーバー</td><td>・メールを送信するための中継サーバー<br>例：Gmailなら <code>smtp.gmail.com</code> </td></tr><tr><td>ポート番号</td><td>・サーバーと通信する入口番号<br>・SMTPでは<span class="marker"> <strong>465（SSL）</strong></span> や <br><strong><span class="marker">587（STARTTLS）</span></strong> がよく使われる</td></tr><tr><td>SSL（465番）</td><td>・通信の最初から最後まで、<strong><span class="marker">ずっと暗号化された状態</span></strong>でやりとりする方式</td></tr><tr><td>STARTTLS（587番）</td><td>・最初は普通の通信で始めて、<strong><span class="marker">途中で暗号化される</span></strong>方式</td></tr><tr><td>認証（Auth）</td><td>・送信者が本人かを確認する仕組み<br>・メールアドレスとアプリパスワードなどでログインする</td></tr><tr><td>host</td><td>・SMTPサーバーのアドレス<br>・<code>smtp.gmail.com</code> や <code>smtp.sendgrid.net</code> のような形</td></tr><tr><td>secure</td><td>・暗号化方式の指定<br>・<span class="marker"><strong><code>true</code> で SSL</strong></span>、<strong><span class="marker"><code>false</code> で STARTTLS</span></strong> を使用</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc5">どっちのポート番号を使えばいいの？【465 or 587】</span></h2>



<p>基本的には <strong><span class="marker">587（STARTTLS）を使うのが推奨</span></strong> です。</p>



<p>多くのメールサービス（Gmail、SendGrid、Outlook など）でも推奨されています。<br></p>



<div class="wp-block-cocoon-blocks-tab-box-1 blank-box bb-tab bb-point block-box has-background has-border-color has-white-background-color has-grey-border-color">
<p class="has-small-font-size"><span class="fz-16px">その理由は</span></p>



<ul class="wp-block-list">
<li><span class="fz-16px">セキュリティ標準として <strong>TLS（STARTTLS）が新しい</strong></span></li>



<li><span class="fz-16px">ファイアウォールやISP（ネット回線業者</span>）<span class="fz-16px">でブロックされにくい</span></li>



<li><span class="fz-16px">相互運用性が高く、失敗しづらい</span></li>
</ul>
</div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc6">465（SSL）を使ってもいいの？</span></h3>



<p>使ってもOKです。ただし注意点もあります。</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>比較項目</th><th>587（STARTTLS）</th><th>465（SSL）</th></tr></thead><tbody><tr><td>推奨度</td><td>推奨されている</td><td>古いがまだ使われている</td></tr><tr><td>安全性</td><td>高い（TLS）</td><td>高い（SSL）※非推奨化の流れ</td></tr><tr><td>対応範囲</td><td>広い</td><td>一部でのサーバーのみ使えることも</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc7">SMTPとPOP/IMAPの違いを比較</span></h2>



<p>メールの送受信には、それぞれ役割の違うプロトコルが使われています。<br>特に、SMTP・POP・IMAPの3つはよく登場しますが、<strong>それぞれ役割がまったく異なります。</strong><br>下の表で、その違いを比べてみましょう。</p>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>プロトコル</th><th>役割</th><th>使いどころ</th></tr></thead><tbody><tr><td><span class="marker"><strong>SMTP</strong></span></td><td>メールを送る</td><td>・Gmailやアプリから送信するときに使われる</td></tr><tr><td><span class="marker"><strong>POP</strong></span></td><td>メールを受け取る（削除型）</td><td>・サーバーから<strong>PCやスマホにダウンロードして削除</strong>する方式<br>・1台の端末だけでメールを管理したいときに向いている</td></tr><tr><td><span class="marker"><strong>IMAP</strong></span></td><td>メールを受け取る（サーバーに残す）</td><td>・メールをサーバー上に<strong>残したまま</strong>アクセス<br>・複数の端末で同じメールを見たいときに便利</td></tr></tbody></table></figure>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/14/status/" title="404？500? ステータスコードとは？よく見るコード厳選まとめ" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-3-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">404？500? ステータスコードとは？よく見るコード厳選まとめ</div><div class="blogcard-snippet internal-blogcard-snippet">開発エンジニアが現場でよく使うHTTPステータスコードを、意味・原因・使われる場面とともにわかりやすく解説！</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc8">SMTPを使った開発実装の例</span></h2>



<p>Web開発では、例えば「お問い合わせフォーム」からの自動返信メールなどにSMTPが使われます。</p>



<p>フォーム入力 → SMTP経由で自動返信メールを送信する流れです。</p>



<ul class="wp-block-list">
<li></li>
</ul>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc9">Node.js + nodemailer の実装例</span></h3>



<p><code>.env</code> にSMTP情報を記載し、それを<code>Node.js</code>で読み込んでメール送信を行うコード例です。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password</code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><textarea class="code-block-pro-copy-button-textarea" aria-hidden="true" readonly>import nodemailer from &#8220;nodemailer&#8221;;
// .env.local に記載した SMTP情報を読み込む
const transporter = nodemailer.createTransport({
  // 接続先のSMTPサーバー
  host: process.env.SMTP_HOST,
  // 使用するポート番号
  port: Number(process.env.SMTP_PORT),
  // ポートが465ならSSL通信（secure: true）、それ以外ならSTARTTLS（secure: false）
  secure: Number(process.env.SMTP_PORT) === 465,
  // 認証情報（メールアドレスとアプリパスワードなど）
  auth: {
    user: process.env.SMTP_USER,
    pass: process.env.SMTP_PASS,
  },
});
// メールの内容
const mailOptions = {
  from: &#8220;your-email@gmail.com&#8221;,
  to: &#8220;receiver@example.com&#8221;,
  subject: &#8220;お問い合わせありがとうございます&#8221;,
  text: &#8220;これは自動返信メールです。&#8221;,
};
// 送信
async function sendEmail() {
  try {
    await transporter.sendMail(mailOptions);
    console.log(&#8220;メール送信に成功しました&#8221;);
  } catch (error) {
    console.error(&#8220;メール送信に失敗しました:&#8221;, error);
  }
}
sendEmail(); // 関数を実行</textarea><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nodemailer</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">nodemailer</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// .env.local に記載した SMTP情報を読み込む</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">transporter</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">nodemailer</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">createTransport</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// 接続先のSMTPサーバー</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">host</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SMTP_HOST</span><span style="color: #ECEFF4">,</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// 使用するポート番号</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">port</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Number</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SMTP_PORT</span><span style="color: #D8DEE9FF">)</span><span style="color: #ECEFF4">,</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// ポートが465ならSSL通信（secure: true）、それ以外ならSTARTTLS（secure: false）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">secure</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">Number</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SMTP_PORT</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">===</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">465</span><span style="color: #ECEFF4">,</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">  </span><span style="color: #616E88">// 認証情報（メールアドレスとアプリパスワードなど）</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">auth</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">user</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SMTP_USER</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">pass</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">process</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">env</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">SMTP_PASS</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// メールの内容</span></span>
<span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mailOptions</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">from</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">your-email@gmail.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">to</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">receiver@example.com</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">subject</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">お問い合わせありがとうございます</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">text</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">これは自動返信メールです。</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">// 送信</span></span>
<span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sendEmail</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">try</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">transporter</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">sendMail</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">mailOptions</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">log</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メール送信に成功しました</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">catch</span><span style="color: #D8DEE9FF"> (</span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF">) </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #D8DEE9">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">error</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">メール送信に失敗しました:</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">error</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #88C0D0">sendEmail</span><span style="color: #D8DEE9FF">()</span><span style="color: #81A1C1">;</span><span style="color: #D8DEE9FF"> </span><span style="color: #616E88">// 関数を実行</span></span></code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading"><span id="toc10">よくある設定ミス：「secureを省略」</span></h3>



<p>SMTP設定で以下のように書いている場合：</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>port: Number(process.env.SMTP_PORT),
secure: Number(process.env.SMTP_PORT) === 465,</code></pre></div>



<p>この <code>secure</code> の指定は<strong>省略せず、明示するのが推奨</strong>です。<br>なぜなら、ポート番号だけでは nodemailer は<strong>どの暗号化方式（SSLかSTARTTLS）を使うか判断できない</strong>からです。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>port: 465,
secure: false  // ← ポート465なのにSSLを使わない ⇒ エラーになる可能性大</code></pre></div>



<p>上記のように設定が矛盾していると、<code>connect error</code> や <code>SSL wrong version number</code> のようなエラーになります。</p>



<p> <span class="badge-green">正しい設定例</span></p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>// SSL（465番）で送信する場合
port: 465,
secure: true,

// STARTTLS（587番）で送信する場合
port: 587,
secure: false,</code></pre></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading"><span id="toc11">SMTPエラーと確認方法</span></h2>



<p>エラーの種類・確認方法の例をご紹介します。<br><br><span class="badge-yellow">エラー確認方法</span> </p>



<ul class="wp-block-list">
<li>開発環境：VSCodeのターミナルに表示</li>



<li>本番環境：ログファイルに記載される等</li>
</ul>



<figure class="wp-block-table is-style-stripes"><table class="has-fixed-layout"><thead><tr><th>エラー表示</th><th>意味</th></tr></thead><tbody><tr><td>SMTP Authentication error</td><td>メールアドレスやパスワード（アプリパスワード）が間違っている</td></tr><tr><td>Connection timeout</td><td>ポSMTPサーバーに接続できない（ポート番号やネット環境の問題）</td></tr><tr><td>550 Relay not permitted</td><td>外部ドメインへの送信がサーバー側で許可されていない</td></tr><tr><td>getaddrinfo ENOTFOUND</td><td>SMTPサーバー名が間違っている、または存在しない</td></tr><tr><td>SSL wrong version number</td><td>ポートと <code>secure</code> の設定が合っていない</td></tr><tr><td>ECONNREFUSED</td><td>サーバーが接続を拒否している（ホスト名やポートのミス）</td></tr><tr><td>Invalid sender address</td><td>from アドレスの形式が正しくない、または拒否された</td></tr></tbody></table></figure>



<p><span class="badge-yellow">例</span><br>認証エラーの場合、ターミナルに下記のようにエラー文が表示されます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-bash" data-lang="Bash"><code>Error: Invalid login: 535-5.7.8 Username and Password not accepted.</code></pre></div>



<div style="height:10px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-cocoon-blocks-blogcard blogcard-type bct-together is-style-normal-card">
<a href="https://it-bokenki.com/2025/06/14/dev-keywords/" title="エンジニアなら押さえたい！基本用語5選" class="blogcard-wrap internal-blogcard-wrap a-wrap cf"><div class="blogcard internal-blogcard ib-left cf"><div class="blogcard-label internal-blogcard-label"><span class="fa"></span></div><figure class="blogcard-thumbnail internal-blogcard-thumbnail"><img loading="lazy" decoding="async" width="320" height="180" src="https://it-bokenki.com/wp-content/uploads/2025/06/２行-6-320x180.png" class="blogcard-thumb-image internal-blogcard-thumb-image wp-post-image" alt="" srcset="https://it-bokenki.com/wp-content/uploads/2025/06/２行-6-320x180.png 320w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-6-120x68.png 120w, https://it-bokenki.com/wp-content/uploads/2025/06/２行-6-160x90.png 160w" sizes="auto, (max-width: 320px) 100vw, 320px" /></figure><div class="blogcard-content internal-blogcard-content"><div class="blogcard-title internal-blogcard-title">エンジニアなら押さえたい！基本用語5選</div><div class="blogcard-snippet internal-blogcard-snippet">現場でよく聞く「ライブラリ」や「フック」などの用語、意味を説明できますか？初心者向けにわかりやすく解説します。</div></div><div class="blogcard-footer internal-blogcard-footer cf"><div class="blogcard-site internal-blogcard-site"><div class="blogcard-favicon internal-blogcard-favicon"><img loading="lazy" decoding="async" src="https://www.google.com/s2/favicons?domain=https://it-bokenki.com" alt="" class="blogcard-favicon-image internal-blogcard-favicon-image" width="16" height="16" /></div><div class="blogcard-domain internal-blogcard-domain">it-bokenki.com</div></div></div></div></a>
<p></p>
</div>



<div style="height:0px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="text-align: center;"><a rel="nofollow" href="https://px.a8.net/svt/ejp?a8mat=457GS5+AI29WY+E0Q+1BQ3UP">
<img loading="lazy" decoding="async" border="0" width="300" height="250" alt="" src="https://www20.a8.net/svt/bgt?aid=250611125635&#038;wid=001&#038;eno=01&#038;mid=s00000001817008016000&#038;mc=1"></a>
<img loading="lazy" decoding="async" border="0" width="1" height="1" src="https://www17.a8.net/0.gif?a8mat=457GS5+AI29WY+E0Q+1BQ3UP" alt=""></div><p>The post <a href="https://it-bokenki.com/2025/06/14/smtp/">SMTPとは？メール送信の仕組みと実装・エラー内容まとめ</a> first appeared on <a href="https://it-bokenki.com">てんハロ｜未経験エンジニアのIT学習ログ</a>.</p>]]></content:encoded>
					
					<wfw:commentRss>https://it-bokenki.com/2025/06/14/smtp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
