1"use strict";(self.webpackChunkwebsite=self.webpackChunkwebsite||[]).push([["6190"],{34531(e,n,r){r.r(n),r.d(n,{metadata:()=>t,default:()=>p,frontMatter:()=>i,contentTitle:()=>c,toc:()=>h,assets:()=>d});var t=JSON.parse('{"id":"restrict-template-expressions","title":"restrict-template-expressions","description":"Enforce template literal expressions to be of `string` type.","source":"@site/../eslint-plugin/docs/rules/restrict-template-expressions.mdx","sourceDirName":".","slug":"/restrict-template-expressions","permalink":"/rules/restrict-template-expressions","draft":false,"unlisted":false,"editUrl":"https://github.com/typescript-eslint/typescript-eslint/edit/main/packages/website/../eslint-plugin/docs/rules/restrict-template-expressions.mdx","tags":[],"version":"current","frontMatter":{"description":"Enforce template literal expressions to be of `string` type.","image":"/img/og/rules/restrict-template-expressions.png"},"sidebar":"rulesSidebar","previous":{"title":"restrict-plus-operands","permalink":"/rules/restrict-plus-operands"},"next":{"title":"return-await","permalink":"/rules/return-await"}}'),s=r(65723),l=r(7143),o=r(70503),a=r(46742);let i={description:"Enforce template literal expressions to be of `string` type.",image:"/img/og/rules/restrict-template-expressions.png"},c,d={},h=[{value:"Examples",id:"examples",level:2},{value:"Options",id:"options",level:2},{value:"<code>allowNumber</code>
1",id:"allownumber",level:3},{value:"<code>allowBoolean</code>",id:"allowboolean",level:3},{value:"<code>allowAny</code>",id:"allowany",level:3},{value:"<code>allowNullish</code>",id:"allownullish",level:3},{value:"<code>allowRegExp</code>",id:"allowregexp",level:3},{value:"<code>allowNever</code>",id:"allownever",level:3},{value:"<code>allowArray</code>",id:"allowarray",level:3},{value:"<code>allow</code>",id:"allow",level:3},{value:"When Not To Use It",id:"when-not-to-use-it",level:2},{value:"Related To",id:"related-to",level:2},{value:"Resources",id:"resources",level:2}];function u(e){let n={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",hr:"hr",li:"li",meta:"meta",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,l.R)(),...e.components},{Head:r,RuleAttributes:t,TryInPlayground:i}=n;return r||x("Head",!0),t||x("RuleAttributes",!0),i||x("TryInPlayground",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.blockquote,{children:["\n",(0,s.jsxs)(n.p,{children:["Enforce template literal expressions to be of ",(0,s.jsx)(n.code,{children:"string"})," type."]}),"\n"]})}),"\n",(0,s.jsx)(t,{name:"restrict-template-expressions"}),"\n","\n",(0,s.jsxs)(n.p,{children:["JavaScript automatically ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#string_coercion",children:"converts an object to a string"})," in a string context, such as when concatenating it with a string using ",(0,s.jsx)(n.code,{children:"+"})," or embedding it in a template literal using ",(0,s.jsx)(n.code,{children:"${}"}),".\nThe default ",(0,s.jsx)(n.code,{children:"toString()"})," method of objects uses the format ",(0,s.jsx)(n.code,{children:'"[object Object]"'}),", which is often not what was intended.\nThis rule reports on values used in a template literal string that aren't strings, optionally allowing other data types that provide useful stringification results."]}),"\n",(0,s.jsxs)(n.admonition,{type:"note",children:[(0,s.jsxs)(n.p,{children:["The default settings of this rule intentionally do not allow objects with a custom ",(0,s.jsx)(n.code,{children:"toString()"})," method to be used in template literals, because the stringification result may not be user-friendly."]}),(0,s.jsxs)(n.p,{children:["For example, arrays have a custom ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toString",children:(0,s.jsx)(n.code,{children:"toString()"})})," method, which only calls ",(0,s.jsx)(n.code,{children:"join()"})," internally, which joins the array elements with commas. This means that (1) array elements are not necessarily stringified to useful results (2) the commas don't have spaces after them, making the result not user-friendly. The best way to format arrays is to use ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat",children:(0,s.jsx)(n.code,{children:"Intl.ListFormat"})}),', which even supports adding the "and" conjunction where necessary.\nYou must explicitly call ',(0,s.jsx)(n.code,{children:"object.toString()"})," if you want to use this object in a template literal, or turn on the ",(0,s.jsx)(n.code,{children:"allowArray"})," option to specifically allow arrays.\nThe ",(0,s.jsx)(n.a,{href:"/rules/no-base-to-string",children:(0,s.jsx)(n.code,{children:"no-base-to-string"})})," rule can be used to guard this case against producing ",(0,s.jsx)(n.code,{children:'"[object Object]"'})," by accident."]})]}),"\n",(0,s.jsxs)(o.A,{children:[(0,s.jsx)(a.A,{value:"Flat Config",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",metastring:'title="eslint.config.mjs"',children:'export default defineConfig({\n rules: {\n "@typescript-eslint/restrict-template-expressions": "error"\n }\n});\n'})})}),(0,s.jsx)(a.A,{value:"Legacy Config",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",metastring:'title=".eslintrc.cjs"',children:'module.exports = {\n "rules": {\n "@typescript-eslint/restrict-template-expressions": "error"\n }\n};\n'})})})]}),"\n",(0,s.jsx)(i,{eslintrcHash:"N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMkRNGhzokcGAC+IHUA",children:(0,s.jsx)(n.p,{children:"Try this rule in the playground \u2197"})}),"\n",(0,s.jsx)(n.h2,{id:"examples",children:"Examples"}),"\n",(0,s.jsxs)(o.A,{children:[(0,s.jsx)(a.A,{value:"\u274C Incorrect",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMkRNGhzokcGAC+IHUA"',children:"const arg1 = [1, 2];\nconst msg1 = `arg1 = ${arg1}`;\n\nconst arg2 = { name: 'Foo' };\nconst msg2 = `arg2 = ${arg2 || null}`;\n"})})}),(0,s.jsx)(a.A,{value:"\u2705 Correct",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMkRNGhzokcGAC+IHUA"',children:"const arg = 'foo';\nconst msg1 = `arg = ${arg}`;\nconst msg2 = `arg = ${arg || 'default'}`;\n\nconst stringWithKindProp: string & { _kind?: 'MyString' } = 'foo';\nconst msg3 = `stringWithKindProp = ${stringWithKindProp}`;\n"})})})]}),"\n",(0,s.jsx)(n.h2,{id:"options",children:"Options"}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["This rule accepts the following options, and has more strict settings in the ",(0,s.jsx)(n.a,{href:"/users/configs#strict",children:"strict"})," and ",(0,s.jsx)(n.a,{href:"/users/configs#strict-type-checked",children:"strict-type-checked"})," configs."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",children:"type Options = [\n {\n /** Types to allow in template expressions. */\n allow?: (\n | {\n from: 'file';\n name: string | string[];\n path?: string;\n }\n | {\n from: 'lib';\n name: string | string[];\n }\n | {\n from: 'package';\n name: string | string[];\n package: string;\n }\n | string\n )[];\n /** Whether to allow `any` typed values in template expressions. */\n allowAny?: boolean;\n /** Whether to allow `array` typed values in template expressions. */\n allowArray?: boolean;\n /** Whether to allow `boolean` typed values in template expressions. */\n allowBoolean?: boolean;\n /** Whether to allow `never` typed values in template expressions. */\n allowNever?: boolean;\n /** Whether to allow `nullish` typed values in template expressions. */\n allowNullish?: boolean;\n /** Whether to allow `number` typed values in template expressions. */\n allowNumber?: boolean;\n /** Whether to allow `regexp` typed values in template expressions. */\n allowRegExp?: boolean;\n },\n];\n\nconst defaultOptionsRecommended: Options = [\n {\n allow: [{ name: ['Error', 'URL', 'URLSearchParams'], from: 'lib' }],\n allowAny: true,\n allowBoolean: true,\n allowNullish: true,\n allowNumber: true,\n allowRegExp: true,\n },\n];\n\n// These options are merged on top of the recommended defaults\nconst defaultOptionsStrict: Options = [\n {\n allowAny: false,\n allowBoolean: false,\n allowNever: false,\n allowNullish: false,\n allowNumber: false,\n allowRegExp: false,\n },\n];\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allownumber",children:(0,s.jsx)(n.code,{children:"allowNumber"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"number"}
1)," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"true"}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowNumber: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowNumber": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4A5WPwBGm9GC6xEh7AF9PAXTU+XkA"',children:"const arg = 123;\nconst msg1 = `arg = ${arg}`;\nconst msg2 = `arg = ${arg || 'zero'}`;\n"})}),"\n",(0,s.jsx)(n.p,{children:"This option controls both numbers and BigInts."}),"\n",(0,s.jsxs)(n.p,{children:["We recommend avoiding using this option if you use any floating point numbers.\nAlthough ",(0,s.jsx)(n.code,{children:"`${1}`"})," evaluates to ",(0,s.jsx)(n.code,{children:"'1'"}),", ",(0,s.jsx)(n.code,{children:"`${0.1 + 0.2}`"})," evaluates to ",(0,s.jsx)(n.code,{children:"'0.30000000000000004'"}),".\nConsider using ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed",children:(0,s.jsx)(n.code,{children:".toFixed()"})})," or ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision",children:(0,s.jsx)(n.code,{children:".toPrecision()"})})," instead."]}),"\n",(0,s.jsx)(n.h3,{id:"allowboolean",children:(0,s.jsx)(n.code,{children:"allowBoolean"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"boolean"})," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"true"}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowBoolean: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowBoolean": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4AhOXKTCm6MF1iJD2AL6eAump8vIA"',children:"const arg = true;\nconst msg1 = `arg = ${arg}`;\nconst msg2 = `arg = ${arg || 'not truthy'}`;\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allowany",children:(0,s.jsx)(n.code,{children:"allowAny"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"any"})," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"true"}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowAny: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowAny": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4BBJoXRgusRIewBfNwF01n90A"',children:"const user = JSON.parse('{ \"name\": \"foo\" }');\nconst msg1 = `arg = ${user.name}`;\nconst msg2 = `arg = ${user.name || 'the user with no name'}`;\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allownullish",children:(0,s.jsx)(n.code,{children:"allowNullish"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"nullish"})," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"true"}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowNullish: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowNullish": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4A5BI2QALdGC6xEh7AF9PAXTU+XkA"',children:"const arg = condition ? 'ok' : null;\nconst msg1 = `arg = ${arg}`;\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allowregexp",children:(0,s.jsx)(n.code,{children:"allowRegExp"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"regexp"})," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"true"}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowRegExp: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowRegExp": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4AlRAHMAopPRgusRIewBfLwF01X28gA"',children:"const arg = new RegExp('foo');\nconst msg1 = `arg = ${arg}`;\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowRegExp": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4AlRAHMAopPRgusRIewBfLwF01X28gA"',children:"const arg = /foo/;\nconst msg1 = `arg = ${arg}`;\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allownever",children:(0,s.jsx)(n.code,{children:"allowNever"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"never"}
1)," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"false"}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowNever: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowNever": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4A5RADdN6MF1iJD2AL4eAumu+eQA"',children:"const arg = 'something';\nconst msg1 = typeof arg === 'string' ? arg : `arg = ${arg}`;\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allowarray",children:(0,s.jsx)(n.code,{children:"allowArray"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Whether to allow ",(0,s.jsx)(n.code,{children:"array"})," typed values in template expressions. Default: ",(0,s.jsx)(n.code,{children:"false"}),"."]})}),"\n","\n",(0,s.jsx)(n.p,{children:"This option recursively checks the type of each array element, so an error is reported if any element has an unacceptable type."}),"\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with ",(0,s.jsx)(n.code,{children:"{ allowArray: true }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'option=\'{ "allowArray": true }\' showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMAbXDYciaNDnRIAGjXqs67JGHx4cgO4BBLcMLowXWIkPYAvu4C6arx6A"',children:"const arg = ['foo', 'bar'];\nconst msg1 = `arg = ${arg}`;\n"})}),"\n",(0,s.jsx)(n.h3,{id:"allow",children:(0,s.jsx)(n.code,{children:"allow"})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Types to allow in template expressions. Default: ",(0,s.jsx)(n.code,{children:'[{ "name": [ "Error", "URL", "URLSearchParams" ], "from": "lib" }]'}),"."]})}),"\n","\n",(0,s.jsxs)(n.p,{children:["This option takes the shared ",(0,s.jsxs)(n.a,{href:"/packages/type-utils/type-or-value-specifier",children:[(0,s.jsx)(n.code,{children:"TypeOrValueSpecifier"})," format"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Examples of additional ",(0,s.jsx)(n.strong,{children:"correct"})," code for this rule with the default option ",(0,s.jsx)(n.code,{children:"{ allow: [{ from: 'lib', name: 'Error' }, { from: 'lib', name: 'URL' }, { from: 'lib', name: 'URLSearchParams' }] }"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-ts",metastring:'showPlaygroundButton eslintrcHash="N4KABGBEBOCuA2BTAzpAXGUEKQAIBcBPABxQGNoBLY-AWhXkoDt8B6aFfKsu-RAW2LwAhn3oAPYh2TJKAeyaoMkRNGhzokcGAC+IHUA"',children:"const error = new Error();\nconst msg1 = `arg = ${error}`;\n"})}),"\n",(0,s.jsx)(n.h2,{id:"when-not-to-use-it",children:"When Not To Use It"}),"\n",(0,s.jsx)(n.p,{children:"If you're not worried about incorrectly stringifying non-string values in template literals, then you likely don't need this rule."}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsx)(n.hr,{})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["Type checked lint rules are more powerful than traditional lint rules, but also require configuring ",(0,s.jsx)(n.a,{href:"/getting-started/typed-linting",children:"type checked linting"}),"."]})}),"\n",(0,s.jsx)(s.Fragment,{children:(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/troubleshooting/typed-linting/performance",children:"Troubleshooting > Linting with Type Information > Performance"})," if you experience performance degradations after enabling type checked rules."]})}),"\n",(0,s.jsx)(n.h2,{id:"related-to",children:"Related To"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/rules/no-base-to-string",children:(0,s.jsx)(n.code,{children:"no-base-to-string"})})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/rules/restrict-plus-operands",children:(0,s.jsx)(n.code,{children:"restrict-plus-operands"})})}),"\n"]}),"\n",(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h2,{id:"resources",children:"Resources"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/rules/restrict-template-expressions.ts",children:"Rule source"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/tests/rules/restrict-template-expressions.test.ts",children:"Test source"})}),"\n"]})]}),"\n",(0,s.jsx)(r,{children:(0,s.jsx)(n.meta,{content:"restrict-template-expressions: Enforce template literal expressions to be of string type",name:"twitter:image:alt"})})]})}function p(e={}){let{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}function x(e,n){throw Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},46742(e,n,r){r.d(n,{A:()=>a});var t=r(65723);r(22155);var s=r(70851),l=r(28226);function o({children:e,className:n,hidden:r}){return(0,t.jsx)("div",{role:"tabpanel",className:(0,s.A)("tabItem_eQ9s",n),hidden:r,children:e})}function a({children:e,className:n,value:r}){let{selectedValue:s,lazy:i}=(0,l.uc)(),c=r===s;return!c&&i?null:(0,t.jsx)(o,{className:n,hidden:!c,children:e})}},70503(e,n,r){r.d(n,{A:()=>u});var t=r(65723);r(22155);var s=r(70851),l=r(98838),o=r(28226),a=r(26309),i=r(29021);function c({className:e}){let{selectedValue:n,selectValue:r,tabValues:l,block:i}=(0,o.uc)(),d=[],{blockElementScrollPositionUntilNextRender:h}=(0,a.a_)(),u=e=>{let t=e.currentTarget,s=l[d.indexOf(t)].value;s!==n&&(h(t),r(s))},p=e=>{let n=null;switch(e.key){case"Enter":u(e);break;case"ArrowRight":{let r=d.indexOf(e.currentTarget)+1;n=d[r]??d[0];break}case"ArrowLeft":{let r=d.indexOf(e.currentTarget)-1;n=d[r]??d[d.length-1]}}n?.focus()};return(0,t.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,s.A)("tabs",{"tabs--block":i},e),children:l.map(({value:e,label:r,attributes:l})=>(0,t.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:e=>{d.push(e)},onKeyDown:p,onClick:u,...l,className:(0,s.A)("tabs__item","tabItem_e1w9",l?.className,{"tabs__item--active":n===e}),children:r??e},e))})}function d({children:e}){return(0,t.jsx)("div",{className:"margin-top--md",children:e})}function h({className:e,children:n}){return(0,t.jsxs)("div",{className:(0,s.A)(l.G.tabs.container,"tabs-container","tabList_mVW_"),children:[(0,t.jsx)(c,{className:e}),(0,t.jsx)(d,{children:n})]})}function u(e){let n=(0,i.A)(),r=(0,o.OC)(e);return(0,t.jsx)(o.O_,{value:r,children:(0,t.jsx)(h,{className:e.className,children:(0,o.vT)(e.children)})},String(n))}},28226(e,n,r){r.d(n,{OC:()=>u,O_:()=>g,uc:()=>x,vT:()=>d});var t=r(65723),s=r(22155),l=r(62934),o=r(24127),a=r(12910),i=r(22399),c=r(6660);function d(e){return s.Children.toArray(e).filter(e=>"\n"!==e)}function h({value:e,tabValues:n}){return n.some(n=>n.value===e)}function u(e){let n,{defaultValue:r,queryString:t=!1,groupId:d}=e,u=function(e){let{values:n,children:r}=e;return(0,s.useMemo)(()=>{let e=n??s.Children.toArray(r).flatMap(e=>{if(!e)return[];if((0,s.isValidElement)(e)&&function(e){let{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return[e];
1let n="string"==typeof e.type?e.type:e.type.name;throw Error(`Docusaurus error: Bad <Tabs> child <${n}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop. 2If you do not want to pass on a "value" prop to the direct children of <Tabs>, you can also pass an explicit <Tabs values={...}> prop.`)}).map(({props:{value:e,label:n,attributes:r,default:t}})=>({value:e,label:n,attributes:r,default:t})),t=(0,i.XI)(e,(e,n)=>e.value===n.value);if(t.length>0)throw Error(`Docusaurus error: Duplicate values "${t.map(e=>`'${e.value}'`).join(", ")}" found in <Tabs>. Every value needs to be unique.`);return e},[n,r])}(e),[p,x]=(0,s.useState)(()=>(function({defaultValue:e,tabValues:n}){if(0===n.length)throw Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!h({value:e,tabValues:n}))throw Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${n.map(e=>e.value).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}let r=n.find(e=>e.default)??n[0];if(!r)throw Error("Unexpected error: 0 tabValues");return r.value})({defaultValue:r,tabValues:u})),[g,m]=function({queryString:e=!1,groupId:n}){let r=(0,l.W6)(),t=function({queryString:e=!1,groupId:n}){if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!n)throw Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return n??null}({queryString:e,groupId:n});return[(0,a.aZ)(t),(0,s.useCallback)(e=>{if(!t)return;let n=new URLSearchParams(r.location.search);n.set(t,e),r.replace({...r.location,search:n.toString()})},[t,r])]}({queryString:t,groupId:d}),[j,A]=function({groupId:e}){let n=e?`docusaurus.tab.${e}`:null,[r,t]=(0,c.Dv)(n);return[r,(0,s.useCallback)(e=>{n&&t.set(e)},[n,t])]}({groupId:d}),f=h({value:n=g??j,tabValues:u})?n:null;return(0,o.A)(()=>{f&&x(f)},[f]),{selectedValue:p,selectValue:(0,s.useCallback)(e=>{if(!h({value:e,tabValues:u}))throw Error(`Can't select invalid tab value=${e}`);x(e),m(e),A(e)},[m,A,u]),tabValues:u,lazy:e.lazy??!1,block:e.block??!1}}let p=(0,s.createContext)(null);function x(){let e=s.useContext(p);if(!e)throw Error("useTabsContext() must be used within a Tabs component");return e}function g(e){return(0,t.jsx)(p.Provider,{value:e.value,children:e.children})}},7143(e,n,r){r.d(n,{R:()=>o,x:()=>a});var t=r(22155);let s={},l=t.createContext(s);function o(e){let n=t.useContext(l);return t.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.