[{"data":1,"prerenderedAt":2277},["ShallowReactive",2],{"navigation_docs":3,"-ai-integration-friendly-type":127,"-ai-integration-friendly-type-surround":2272},[4,19,53,71,95],{"title":5,"icon":6,"redirect":7,"path":8,"stem":9,"children":10,"page":18},"Introduction","i-lucide-rocket","\u002Fintroduction\u002Fabout-ts-runtypes","\u002Fintroduction","1.introduction",[11,14],{"title":12,"path":7,"stem":13},"About RunTypes","1.introduction\u002F1.about-ts-runtypes",{"title":15,"path":16,"stem":17},"Quick Start","\u002Fintroduction\u002Fquick-start","1.introduction\u002F2.quick-start",false,{"title":20,"icon":21,"redirect":22,"path":23,"stem":24,"children":25,"page":18},"Guide","i-lucide-book-open","\u002Fguide\u002Ftypes-vs-schemas","\u002Fguide","2.guide",[26,29,33,37,41,45,49],{"title":27,"path":22,"stem":28},"Types vs Schemas","2.guide\u002F1.types-vs-schemas",{"title":30,"path":31,"stem":32},"Type Formats","\u002Fguide\u002Ftype-formats","2.guide\u002F2.type-formats",{"title":34,"path":35,"stem":36},"Serialization","\u002Fguide\u002Fserialization","2.guide\u002F3.serialization",{"title":38,"path":39,"stem":40},"Mock Data","\u002Fguide\u002Fmocking","2.guide\u002F4.mocking",{"title":42,"path":43,"stem":44},"Validation","\u002Fguide\u002Fvalidation","2.guide\u002F5.validation",{"title":46,"path":47,"stem":48},"Reflection","\u002Fguide\u002Fmarkers-and-reflection","2.guide\u002F6.markers-and-reflection",{"title":50,"path":51,"stem":52},"Pure Functions","\u002Fguide\u002Fpure-functions","2.guide\u002F7.pure-functions",{"title":54,"icon":55,"redirect":56,"path":57,"stem":58,"children":59,"page":18},"AI Integration","i-lucide-sparkles","\u002Fai-integration\u002Fworkflow-and-commands","\u002Fai-integration","3.ai-integration",[60,63,67],{"title":61,"path":56,"stem":62},"AI Workflow","3.ai-integration\u002F1.workflow-and-commands",{"title":64,"path":65,"stem":66},"FriendlyType","\u002Fai-integration\u002Ffriendly-type","3.ai-integration\u002F2.friendly-type",{"title":68,"path":69,"stem":70},"MockData","\u002Fai-integration\u002Fmock-data","3.ai-integration\u002F3.mock-data",{"title":72,"icon":73,"redirect":74,"path":75,"stem":76,"children":77,"page":18},"Test Suites","i-lucide-terminal","\u002Fsuites\u002Fvalidation","\u002Fsuites","6.suites",[78,80,83,87,91],{"title":42,"path":74,"stem":79},"6.suites\u002F1.validation",{"title":34,"path":81,"stem":82},"\u002Fsuites\u002Fserialization","6.suites\u002F2.serialization",{"title":84,"path":85,"stem":86},"Formats Validation","\u002Fsuites\u002Fformat-validation","6.suites\u002F3.format-validation",{"title":88,"path":89,"stem":90},"Formats Serialization","\u002Fsuites\u002Fformat-serialization","6.suites\u002F4.format-serialization",{"title":92,"path":93,"stem":94},"Fuzzing","\u002Fsuites\u002Ffuzzing","6.suites\u002F5.fuzzing",{"title":96,"icon":97,"redirect":98,"path":99,"stem":100,"children":101,"page":18},"Benchmarks","i-lucide-gauge","\u002Fbenchmarks\u002Fvalidation","\u002Fbenchmarks","7.benchmarks",[102,104,108,112,116,119,123],{"title":42,"path":98,"stem":103},"7.benchmarks\u002F1.validation",{"title":105,"path":106,"stem":107},"Validation Formats","\u002Fbenchmarks\u002Fvalidation-formats","7.benchmarks\u002F2.validation-formats",{"title":109,"path":110,"stem":111},"Validation Errors","\u002Fbenchmarks\u002Fgetvalidationerrors","7.benchmarks\u002F3.getvalidationerrors",{"title":113,"path":114,"stem":115},"Validation Error Formats","\u002Fbenchmarks\u002Fgetvalidationerrors-formats","7.benchmarks\u002F4.getvalidationerrors-formats",{"title":34,"path":117,"stem":118},"\u002Fbenchmarks\u002Fserialization","7.benchmarks\u002F5.serialization",{"title":120,"path":121,"stem":122},"Serialization Formats","\u002Fbenchmarks\u002Fserialization-formats","7.benchmarks\u002F6.serialization-formats",{"title":124,"path":125,"stem":126},"Compile Time","\u002Fbenchmarks\u002Fcompiletime","7.benchmarks\u002F7.compiletime",{"id":128,"title":64,"body":129,"description":2266,"extension":2267,"links":2268,"meta":2269,"navigation":243,"path":65,"seo":2270,"stem":66,"__hash__":2271},"docs\u002F3.ai-integration\u002F2.friendly-type.md",{"type":130,"value":131},"minimark",[132,154,159,175,186,1417,1424,1428,1450,1619,1637,1654,1658,1665,1734,1744,1748,1762,2006,2013,2020,2027,2169,2185,2246,2255,2262],[133,134,135,139,140,144,145,148,149,153],"p",{},[136,137,138],"code",{},"FriendlyType\u003CT>"," is a human-readable map for a type, giving a ",[141,142,143],"strong",{},"label"," and ",[141,146,147],{},"error messages"," to each field. You author it once, ",[150,151,152],"a",{"href":56},"commit"," it next to your type, and the compiler checks it against that type on every build. Use it to turn validation errors into messages people can actually read.",[155,156,158],"h2",{"id":157},"how-its-shaped","How it's shaped",[133,160,161,162,165,166,169,170,174],{},"The map mirrors your type. Every node is ",[136,163,164],{},"{ $label?, $errors?, ...fields }",". The ",[136,167,168],{},"$"," keys hold the label and error messages for ",[171,172,173],"em",{},"this"," field, and every other key is a child field. It nests the same way all the way down.",[133,176,177,178,181,182,185],{},"The compiler scaffolds the map from your type with every field in place and each blank marked ",[136,179,180],{},"@todo",", then the agent fills those blanks. The map is validated against ",[136,183,184],{},"User"," at scan time, so a stale key or a structural mismatch is a build-time Error.",[187,188,189,452,934],"code-group",{},[190,191,197],"pre",{"className":192,"code":193,"filename":194,"language":195,"meta":196,"style":196},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import type * as TF from 'ts-runtypes\u002Fformats';\n\n\u002F\u002F models\u002Fuser.ts\nexport interface User {\n  name: TF.String\u003C{ minLength: 2; maxLength: 60 }>;\n  age: TF.Number\u003C{ min: 0; max: 120 }>;\n  isActive: boolean;\n  tags: string[];\n  profile: {\n    email: TF.Email;\n    score: TF.Number\u003C{ min: 0; max: 100 }>;\n  };\n}\n","Your type","ts","",[136,198,199,238,245,252,269,314,351,364,380,390,407,440,446],{"__ignoreMap":196},[200,201,204,208,211,215,218,222,225,228,232,235],"span",{"class":202,"line":203},"line",1,[200,205,207],{"class":206},"s7zQu","import",[200,209,210],{"class":206}," type",[200,212,214],{"class":213},"sMK4o"," *",[200,216,217],{"class":206}," as",[200,219,221],{"class":220},"sTEyZ"," TF ",[200,223,224],{"class":206},"from",[200,226,227],{"class":213}," '",[200,229,231],{"class":230},"sfazB","ts-runtypes\u002Fformats",[200,233,234],{"class":213},"'",[200,236,237],{"class":213},";\n",[200,239,241],{"class":202,"line":240},2,[200,242,244],{"emptyLinePlaceholder":243},true,"\n",[200,246,248],{"class":202,"line":247},3,[200,249,251],{"class":250},"sHwdD","\u002F\u002F models\u002Fuser.ts\n",[200,253,255,258,262,266],{"class":202,"line":254},4,[200,256,257],{"class":206},"export",[200,259,261],{"class":260},"spNyl"," interface",[200,263,265],{"class":264},"sBMFI"," User",[200,267,268],{"class":213}," {\n",[200,270,272,276,279,282,285,288,291,294,296,300,303,306,308,311],{"class":202,"line":271},5,[200,273,275],{"class":274},"swJcz","  name",[200,277,278],{"class":213},":",[200,280,281],{"class":264}," TF",[200,283,284],{"class":213},".",[200,286,287],{"class":264},"String",[200,289,290],{"class":213},"\u003C{",[200,292,293],{"class":274}," minLength",[200,295,278],{"class":213},[200,297,299],{"class":298},"sbssI"," 2",[200,301,302],{"class":213},";",[200,304,305],{"class":274}," maxLength",[200,307,278],{"class":213},[200,309,310],{"class":298}," 60",[200,312,313],{"class":213}," }>;\n",[200,315,317,320,322,324,326,329,331,334,336,339,341,344,346,349],{"class":202,"line":316},6,[200,318,319],{"class":274},"  age",[200,321,278],{"class":213},[200,323,281],{"class":264},[200,325,284],{"class":213},[200,327,328],{"class":264},"Number",[200,330,290],{"class":213},[200,332,333],{"class":274}," min",[200,335,278],{"class":213},[200,337,338],{"class":298}," 0",[200,340,302],{"class":213},[200,342,343],{"class":274}," max",[200,345,278],{"class":213},[200,347,348],{"class":298}," 120",[200,350,313],{"class":213},[200,352,354,357,359,362],{"class":202,"line":353},7,[200,355,356],{"class":274},"  isActive",[200,358,278],{"class":213},[200,360,361],{"class":264}," boolean",[200,363,237],{"class":213},[200,365,367,370,372,375,378],{"class":202,"line":366},8,[200,368,369],{"class":274},"  tags",[200,371,278],{"class":213},[200,373,374],{"class":264}," string",[200,376,377],{"class":220},"[]",[200,379,237],{"class":213},[200,381,383,386,388],{"class":202,"line":382},9,[200,384,385],{"class":274},"  profile",[200,387,278],{"class":213},[200,389,268],{"class":213},[200,391,393,396,398,400,402,405],{"class":202,"line":392},10,[200,394,395],{"class":274},"    email",[200,397,278],{"class":213},[200,399,281],{"class":264},[200,401,284],{"class":213},[200,403,404],{"class":264},"Email",[200,406,237],{"class":213},[200,408,410,413,415,417,419,421,423,425,427,429,431,433,435,438],{"class":202,"line":409},11,[200,411,412],{"class":274},"    score",[200,414,278],{"class":213},[200,416,281],{"class":264},[200,418,284],{"class":213},[200,420,328],{"class":264},[200,422,290],{"class":213},[200,424,333],{"class":274},[200,426,278],{"class":213},[200,428,338],{"class":298},[200,430,302],{"class":213},[200,432,343],{"class":274},[200,434,278],{"class":213},[200,436,437],{"class":298}," 100",[200,439,313],{"class":213},[200,441,443],{"class":202,"line":442},12,[200,444,445],{"class":213},"  };\n",[200,447,449],{"class":202,"line":448},13,[200,450,451],{"class":213},"}\n",[190,453,456],{"className":192,"code":454,"filename":455,"language":195,"meta":196,"style":196},"import type { FriendlyType } from 'ts-runtypes';\nimport type { User } from '.\u002Fuser';\n\n\u002F\u002F scaffolded by `gen`: every field in place, each blank marked @todo\nexport const userFriendly: FriendlyType\u003CUser> = {\n  $label: '', \u002F\u002F @todo\n\n  name: {\n    $label: '', \u002F\u002F @todo\n    $errors: {\n      type: '',      \u002F\u002F @todo\n      minLength: '', \u002F\u002F @todo\n      maxLength: '', \u002F\u002F @todo\n    },\n  },\n  age: {\n    $label: '', \u002F\u002F @todo\n    $errors: {\n      type: '', \u002F\u002F @todo\n      min: '',  \u002F\u002F @todo\n      max: '',  \u002F\u002F @todo\n    },\n  },\n  isActive: { $label: '' }, \u002F\u002F @todo\n\n  tags: {\n    $label: '', \u002F\u002F @todo\n    $items: { $errors: { type: '' } },   \u002F\u002F @todo element node\n  },\n\n  profile: {                          \u002F\u002F nested object: same node shape\n    $label: '', \u002F\u002F @todo\n    email: { $label: '', $errors: { pattern: '' } },          \u002F\u002F @todo\n    score: { $label: '', $errors: { min: '', max: '' } },     \u002F\u002F @todo\n  },\n};\n","Generated by the compiler",[136,457,458,485,508,512,517,544,560,564,572,585,594,608,621,634,640,646,655,668,677,690,705,719,724,729,750,755,764,777,807,812,817,829,842,879,923,928],{"__ignoreMap":196},[200,459,460,462,464,467,470,473,476,478,481,483],{"class":202,"line":203},[200,461,207],{"class":206},[200,463,210],{"class":206},[200,465,466],{"class":213}," {",[200,468,469],{"class":220}," FriendlyType",[200,471,472],{"class":213}," }",[200,474,475],{"class":206}," from",[200,477,227],{"class":213},[200,479,480],{"class":230},"ts-runtypes",[200,482,234],{"class":213},[200,484,237],{"class":213},[200,486,487,489,491,493,495,497,499,501,504,506],{"class":202,"line":240},[200,488,207],{"class":206},[200,490,210],{"class":206},[200,492,466],{"class":213},[200,494,265],{"class":220},[200,496,472],{"class":213},[200,498,475],{"class":206},[200,500,227],{"class":213},[200,502,503],{"class":230},".\u002Fuser",[200,505,234],{"class":213},[200,507,237],{"class":213},[200,509,510],{"class":202,"line":247},[200,511,244],{"emptyLinePlaceholder":243},[200,513,514],{"class":202,"line":254},[200,515,516],{"class":250},"\u002F\u002F scaffolded by `gen`: every field in place, each blank marked @todo\n",[200,518,519,521,524,527,529,531,534,536,539,542],{"class":202,"line":271},[200,520,257],{"class":206},[200,522,523],{"class":260}," const",[200,525,526],{"class":220}," userFriendly",[200,528,278],{"class":213},[200,530,469],{"class":264},[200,532,533],{"class":213},"\u003C",[200,535,184],{"class":264},[200,537,538],{"class":213},">",[200,540,541],{"class":213}," =",[200,543,268],{"class":213},[200,545,546,549,551,554,557],{"class":202,"line":316},[200,547,548],{"class":274},"  $label",[200,550,278],{"class":213},[200,552,553],{"class":213}," ''",[200,555,556],{"class":213},",",[200,558,559],{"class":250}," \u002F\u002F @todo\n",[200,561,562],{"class":202,"line":353},[200,563,244],{"emptyLinePlaceholder":243},[200,565,566,568,570],{"class":202,"line":366},[200,567,275],{"class":274},[200,569,278],{"class":213},[200,571,268],{"class":213},[200,573,574,577,579,581,583],{"class":202,"line":382},[200,575,576],{"class":274},"    $label",[200,578,278],{"class":213},[200,580,553],{"class":213},[200,582,556],{"class":213},[200,584,559],{"class":250},[200,586,587,590,592],{"class":202,"line":392},[200,588,589],{"class":274},"    $errors",[200,591,278],{"class":213},[200,593,268],{"class":213},[200,595,596,599,601,603,605],{"class":202,"line":409},[200,597,598],{"class":274},"      type",[200,600,278],{"class":213},[200,602,553],{"class":213},[200,604,556],{"class":213},[200,606,607],{"class":250},"      \u002F\u002F @todo\n",[200,609,610,613,615,617,619],{"class":202,"line":442},[200,611,612],{"class":274},"      minLength",[200,614,278],{"class":213},[200,616,553],{"class":213},[200,618,556],{"class":213},[200,620,559],{"class":250},[200,622,623,626,628,630,632],{"class":202,"line":448},[200,624,625],{"class":274},"      maxLength",[200,627,278],{"class":213},[200,629,553],{"class":213},[200,631,556],{"class":213},[200,633,559],{"class":250},[200,635,637],{"class":202,"line":636},14,[200,638,639],{"class":213},"    },\n",[200,641,643],{"class":202,"line":642},15,[200,644,645],{"class":213},"  },\n",[200,647,649,651,653],{"class":202,"line":648},16,[200,650,319],{"class":274},[200,652,278],{"class":213},[200,654,268],{"class":213},[200,656,658,660,662,664,666],{"class":202,"line":657},17,[200,659,576],{"class":274},[200,661,278],{"class":213},[200,663,553],{"class":213},[200,665,556],{"class":213},[200,667,559],{"class":250},[200,669,671,673,675],{"class":202,"line":670},18,[200,672,589],{"class":274},[200,674,278],{"class":213},[200,676,268],{"class":213},[200,678,680,682,684,686,688],{"class":202,"line":679},19,[200,681,598],{"class":274},[200,683,278],{"class":213},[200,685,553],{"class":213},[200,687,556],{"class":213},[200,689,559],{"class":250},[200,691,693,696,698,700,702],{"class":202,"line":692},20,[200,694,695],{"class":274},"      min",[200,697,278],{"class":213},[200,699,553],{"class":213},[200,701,556],{"class":213},[200,703,704],{"class":250},"  \u002F\u002F @todo\n",[200,706,708,711,713,715,717],{"class":202,"line":707},21,[200,709,710],{"class":274},"      max",[200,712,278],{"class":213},[200,714,553],{"class":213},[200,716,556],{"class":213},[200,718,704],{"class":250},[200,720,722],{"class":202,"line":721},22,[200,723,639],{"class":213},[200,725,727],{"class":202,"line":726},23,[200,728,645],{"class":213},[200,730,732,734,736,738,741,743,745,748],{"class":202,"line":731},24,[200,733,356],{"class":274},[200,735,278],{"class":213},[200,737,466],{"class":213},[200,739,740],{"class":274}," $label",[200,742,278],{"class":213},[200,744,553],{"class":213},[200,746,747],{"class":213}," },",[200,749,559],{"class":250},[200,751,753],{"class":202,"line":752},25,[200,754,244],{"emptyLinePlaceholder":243},[200,756,758,760,762],{"class":202,"line":757},26,[200,759,369],{"class":274},[200,761,278],{"class":213},[200,763,268],{"class":213},[200,765,767,769,771,773,775],{"class":202,"line":766},27,[200,768,576],{"class":274},[200,770,278],{"class":213},[200,772,553],{"class":213},[200,774,556],{"class":213},[200,776,559],{"class":250},[200,778,780,783,785,787,790,792,794,796,798,800,802,804],{"class":202,"line":779},28,[200,781,782],{"class":274},"    $items",[200,784,278],{"class":213},[200,786,466],{"class":213},[200,788,789],{"class":274}," $errors",[200,791,278],{"class":213},[200,793,466],{"class":213},[200,795,210],{"class":274},[200,797,278],{"class":213},[200,799,553],{"class":213},[200,801,472],{"class":213},[200,803,747],{"class":213},[200,805,806],{"class":250},"   \u002F\u002F @todo element node\n",[200,808,810],{"class":202,"line":809},29,[200,811,645],{"class":213},[200,813,815],{"class":202,"line":814},30,[200,816,244],{"emptyLinePlaceholder":243},[200,818,820,822,824,826],{"class":202,"line":819},31,[200,821,385],{"class":274},[200,823,278],{"class":213},[200,825,466],{"class":213},[200,827,828],{"class":250},"                          \u002F\u002F nested object: same node shape\n",[200,830,832,834,836,838,840],{"class":202,"line":831},32,[200,833,576],{"class":274},[200,835,278],{"class":213},[200,837,553],{"class":213},[200,839,556],{"class":213},[200,841,559],{"class":250},[200,843,845,847,849,851,853,855,857,859,861,863,865,868,870,872,874,876],{"class":202,"line":844},33,[200,846,395],{"class":274},[200,848,278],{"class":213},[200,850,466],{"class":213},[200,852,740],{"class":274},[200,854,278],{"class":213},[200,856,553],{"class":213},[200,858,556],{"class":213},[200,860,789],{"class":274},[200,862,278],{"class":213},[200,864,466],{"class":213},[200,866,867],{"class":274}," pattern",[200,869,278],{"class":213},[200,871,553],{"class":213},[200,873,472],{"class":213},[200,875,747],{"class":213},[200,877,878],{"class":250},"          \u002F\u002F @todo\n",[200,880,882,884,886,888,890,892,894,896,898,900,902,904,906,908,910,912,914,916,918,920],{"class":202,"line":881},34,[200,883,412],{"class":274},[200,885,278],{"class":213},[200,887,466],{"class":213},[200,889,740],{"class":274},[200,891,278],{"class":213},[200,893,553],{"class":213},[200,895,556],{"class":213},[200,897,789],{"class":274},[200,899,278],{"class":213},[200,901,466],{"class":213},[200,903,333],{"class":274},[200,905,278],{"class":213},[200,907,553],{"class":213},[200,909,556],{"class":213},[200,911,343],{"class":274},[200,913,278],{"class":213},[200,915,553],{"class":213},[200,917,472],{"class":213},[200,919,747],{"class":213},[200,921,922],{"class":250},"     \u002F\u002F @todo\n",[200,924,926],{"class":202,"line":925},35,[200,927,645],{"class":213},[200,929,931],{"class":202,"line":930},36,[200,932,933],{"class":213},"};\n",[190,935,938],{"className":192,"code":936,"filename":937,"language":195,"meta":196,"style":196},"import type { FriendlyType } from 'ts-runtypes';\nimport type { User } from '.\u002Fuser';\n\nexport const userFriendly: FriendlyType\u003CUser> = {\n  $label: 'User account',\n\n  name: {\n    $label: 'Full name',\n    $errors: {\n      type: '$[label] must be text',\n      minLength: '$[label] needs at least $[val] characters',\n      maxLength: '$[label] allows at most $[val] characters',\n    },\n  },\n  age: {\n    $label: 'Age',\n    $errors: {\n      type: '$[label] must be a number',\n      min: '$[label] must be at least $[val]',\n      max: '$[label] must be no more than $[val]',\n    },\n  },\n  isActive: { $label: 'Active?' },\n\n  tags: {\n    $label: 'Tags',\n    $items: { $errors: { type: 'each tag must be text' } },   \u002F\u002F element node\n  },\n\n  profile: {                          \u002F\u002F nested object: same node shape, recursively\n    $label: 'Profile',\n    email: { $label: 'Email', $errors: { pattern: 'Enter a valid email address' } },\n    score: { $label: 'Score', $errors: { min: 'min $[val]', max: 'max $[val]' } },\n  },\n};\n","Filled by the agent",[136,939,940,962,984,988,1010,1026,1030,1038,1053,1061,1076,1091,1106,1110,1114,1122,1137,1145,1160,1175,1190,1194,1198,1220,1224,1232,1247,1279,1283,1287,1298,1313,1354,1409,1413],{"__ignoreMap":196},[200,941,942,944,946,948,950,952,954,956,958,960],{"class":202,"line":203},[200,943,207],{"class":206},[200,945,210],{"class":206},[200,947,466],{"class":213},[200,949,469],{"class":220},[200,951,472],{"class":213},[200,953,475],{"class":206},[200,955,227],{"class":213},[200,957,480],{"class":230},[200,959,234],{"class":213},[200,961,237],{"class":213},[200,963,964,966,968,970,972,974,976,978,980,982],{"class":202,"line":240},[200,965,207],{"class":206},[200,967,210],{"class":206},[200,969,466],{"class":213},[200,971,265],{"class":220},[200,973,472],{"class":213},[200,975,475],{"class":206},[200,977,227],{"class":213},[200,979,503],{"class":230},[200,981,234],{"class":213},[200,983,237],{"class":213},[200,985,986],{"class":202,"line":247},[200,987,244],{"emptyLinePlaceholder":243},[200,989,990,992,994,996,998,1000,1002,1004,1006,1008],{"class":202,"line":254},[200,991,257],{"class":206},[200,993,523],{"class":260},[200,995,526],{"class":220},[200,997,278],{"class":213},[200,999,469],{"class":264},[200,1001,533],{"class":213},[200,1003,184],{"class":264},[200,1005,538],{"class":213},[200,1007,541],{"class":213},[200,1009,268],{"class":213},[200,1011,1012,1014,1016,1018,1021,1023],{"class":202,"line":271},[200,1013,548],{"class":274},[200,1015,278],{"class":213},[200,1017,227],{"class":213},[200,1019,1020],{"class":230},"User account",[200,1022,234],{"class":213},[200,1024,1025],{"class":213},",\n",[200,1027,1028],{"class":202,"line":316},[200,1029,244],{"emptyLinePlaceholder":243},[200,1031,1032,1034,1036],{"class":202,"line":353},[200,1033,275],{"class":274},[200,1035,278],{"class":213},[200,1037,268],{"class":213},[200,1039,1040,1042,1044,1046,1049,1051],{"class":202,"line":366},[200,1041,576],{"class":274},[200,1043,278],{"class":213},[200,1045,227],{"class":213},[200,1047,1048],{"class":230},"Full name",[200,1050,234],{"class":213},[200,1052,1025],{"class":213},[200,1054,1055,1057,1059],{"class":202,"line":382},[200,1056,589],{"class":274},[200,1058,278],{"class":213},[200,1060,268],{"class":213},[200,1062,1063,1065,1067,1069,1072,1074],{"class":202,"line":392},[200,1064,598],{"class":274},[200,1066,278],{"class":213},[200,1068,227],{"class":213},[200,1070,1071],{"class":230},"$[label] must be text",[200,1073,234],{"class":213},[200,1075,1025],{"class":213},[200,1077,1078,1080,1082,1084,1087,1089],{"class":202,"line":409},[200,1079,612],{"class":274},[200,1081,278],{"class":213},[200,1083,227],{"class":213},[200,1085,1086],{"class":230},"$[label] needs at least $[val] characters",[200,1088,234],{"class":213},[200,1090,1025],{"class":213},[200,1092,1093,1095,1097,1099,1102,1104],{"class":202,"line":442},[200,1094,625],{"class":274},[200,1096,278],{"class":213},[200,1098,227],{"class":213},[200,1100,1101],{"class":230},"$[label] allows at most $[val] characters",[200,1103,234],{"class":213},[200,1105,1025],{"class":213},[200,1107,1108],{"class":202,"line":448},[200,1109,639],{"class":213},[200,1111,1112],{"class":202,"line":636},[200,1113,645],{"class":213},[200,1115,1116,1118,1120],{"class":202,"line":642},[200,1117,319],{"class":274},[200,1119,278],{"class":213},[200,1121,268],{"class":213},[200,1123,1124,1126,1128,1130,1133,1135],{"class":202,"line":648},[200,1125,576],{"class":274},[200,1127,278],{"class":213},[200,1129,227],{"class":213},[200,1131,1132],{"class":230},"Age",[200,1134,234],{"class":213},[200,1136,1025],{"class":213},[200,1138,1139,1141,1143],{"class":202,"line":657},[200,1140,589],{"class":274},[200,1142,278],{"class":213},[200,1144,268],{"class":213},[200,1146,1147,1149,1151,1153,1156,1158],{"class":202,"line":670},[200,1148,598],{"class":274},[200,1150,278],{"class":213},[200,1152,227],{"class":213},[200,1154,1155],{"class":230},"$[label] must be a number",[200,1157,234],{"class":213},[200,1159,1025],{"class":213},[200,1161,1162,1164,1166,1168,1171,1173],{"class":202,"line":679},[200,1163,695],{"class":274},[200,1165,278],{"class":213},[200,1167,227],{"class":213},[200,1169,1170],{"class":230},"$[label] must be at least $[val]",[200,1172,234],{"class":213},[200,1174,1025],{"class":213},[200,1176,1177,1179,1181,1183,1186,1188],{"class":202,"line":692},[200,1178,710],{"class":274},[200,1180,278],{"class":213},[200,1182,227],{"class":213},[200,1184,1185],{"class":230},"$[label] must be no more than $[val]",[200,1187,234],{"class":213},[200,1189,1025],{"class":213},[200,1191,1192],{"class":202,"line":707},[200,1193,639],{"class":213},[200,1195,1196],{"class":202,"line":721},[200,1197,645],{"class":213},[200,1199,1200,1202,1204,1206,1208,1210,1212,1215,1217],{"class":202,"line":726},[200,1201,356],{"class":274},[200,1203,278],{"class":213},[200,1205,466],{"class":213},[200,1207,740],{"class":274},[200,1209,278],{"class":213},[200,1211,227],{"class":213},[200,1213,1214],{"class":230},"Active?",[200,1216,234],{"class":213},[200,1218,1219],{"class":213}," },\n",[200,1221,1222],{"class":202,"line":731},[200,1223,244],{"emptyLinePlaceholder":243},[200,1225,1226,1228,1230],{"class":202,"line":752},[200,1227,369],{"class":274},[200,1229,278],{"class":213},[200,1231,268],{"class":213},[200,1233,1234,1236,1238,1240,1243,1245],{"class":202,"line":757},[200,1235,576],{"class":274},[200,1237,278],{"class":213},[200,1239,227],{"class":213},[200,1241,1242],{"class":230},"Tags",[200,1244,234],{"class":213},[200,1246,1025],{"class":213},[200,1248,1249,1251,1253,1255,1257,1259,1261,1263,1265,1267,1270,1272,1274,1276],{"class":202,"line":766},[200,1250,782],{"class":274},[200,1252,278],{"class":213},[200,1254,466],{"class":213},[200,1256,789],{"class":274},[200,1258,278],{"class":213},[200,1260,466],{"class":213},[200,1262,210],{"class":274},[200,1264,278],{"class":213},[200,1266,227],{"class":213},[200,1268,1269],{"class":230},"each tag must be text",[200,1271,234],{"class":213},[200,1273,472],{"class":213},[200,1275,747],{"class":213},[200,1277,1278],{"class":250},"   \u002F\u002F element node\n",[200,1280,1281],{"class":202,"line":779},[200,1282,645],{"class":213},[200,1284,1285],{"class":202,"line":809},[200,1286,244],{"emptyLinePlaceholder":243},[200,1288,1289,1291,1293,1295],{"class":202,"line":814},[200,1290,385],{"class":274},[200,1292,278],{"class":213},[200,1294,466],{"class":213},[200,1296,1297],{"class":250},"                          \u002F\u002F nested object: same node shape, recursively\n",[200,1299,1300,1302,1304,1306,1309,1311],{"class":202,"line":819},[200,1301,576],{"class":274},[200,1303,278],{"class":213},[200,1305,227],{"class":213},[200,1307,1308],{"class":230},"Profile",[200,1310,234],{"class":213},[200,1312,1025],{"class":213},[200,1314,1315,1317,1319,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1348,1350,1352],{"class":202,"line":831},[200,1316,395],{"class":274},[200,1318,278],{"class":213},[200,1320,466],{"class":213},[200,1322,740],{"class":274},[200,1324,278],{"class":213},[200,1326,227],{"class":213},[200,1328,404],{"class":230},[200,1330,234],{"class":213},[200,1332,556],{"class":213},[200,1334,789],{"class":274},[200,1336,278],{"class":213},[200,1338,466],{"class":213},[200,1340,867],{"class":274},[200,1342,278],{"class":213},[200,1344,227],{"class":213},[200,1346,1347],{"class":230},"Enter a valid email address",[200,1349,234],{"class":213},[200,1351,472],{"class":213},[200,1353,1219],{"class":213},[200,1355,1356,1358,1360,1362,1364,1366,1368,1371,1373,1375,1377,1379,1381,1383,1385,1387,1390,1392,1394,1396,1398,1400,1403,1405,1407],{"class":202,"line":844},[200,1357,412],{"class":274},[200,1359,278],{"class":213},[200,1361,466],{"class":213},[200,1363,740],{"class":274},[200,1365,278],{"class":213},[200,1367,227],{"class":213},[200,1369,1370],{"class":230},"Score",[200,1372,234],{"class":213},[200,1374,556],{"class":213},[200,1376,789],{"class":274},[200,1378,278],{"class":213},[200,1380,466],{"class":213},[200,1382,333],{"class":274},[200,1384,278],{"class":213},[200,1386,227],{"class":213},[200,1388,1389],{"class":230},"min $[val]",[200,1391,234],{"class":213},[200,1393,556],{"class":213},[200,1395,343],{"class":274},[200,1397,278],{"class":213},[200,1399,227],{"class":213},[200,1401,1402],{"class":230},"max $[val]",[200,1404,234],{"class":213},[200,1406,472],{"class":213},[200,1408,1219],{"class":213},[200,1410,1411],{"class":202,"line":881},[200,1412,645],{"class":213},[200,1414,1415],{"class":202,"line":925},[200,1416,933],{"class":213},[133,1418,1419,1420,1423],{},"Container meta keys follow the type's shape: arrays and tuples use ",[136,1421,1422],{},"$items"," for the element node; objects nest as the same node, recursively.",[155,1425,1427],{"id":1426},"error-keys-name-the-rule-that-failed","Error keys name the rule that failed",[133,1429,1430,1431,1434,1435,1438,1439,1438,1442,1445,1446,1449],{},"Each ",[136,1432,1433],{},"$errors"," key names a specific rule the value broke: ",[136,1436,1437],{},"minLength",", ",[136,1440,1441],{},"pattern",[136,1443,1444],{},"min",", and so on. ",[136,1447,1448],{},"type"," is the catch-all for a value that's the wrong kind entirely (text where a number was expected). The keys aren't made up; they line up exactly with what the validator reports.",[1451,1452,1453,1474],"table",{},[1454,1455,1456],"thead",{},[1457,1458,1459,1463,1468],"tr",{},[1460,1461,1462],"th",{},"Failure",[1460,1464,1465,1467],{},[136,1466,1433],{}," key",[1460,1469,1470,1473],{},[136,1471,1472],{},"$[val]"," resolves to",[1475,1476,1477,1490,1517,1529,1548,1566,1582,1601],"tbody",{},[1457,1478,1479,1483,1487],{},[1480,1481,1482],"td",{},"base type-shape (wrong kind)",[1480,1484,1485],{},[136,1486,1448],{},[1480,1488,1489],{},"n\u002Fa",[1457,1491,1492,1501,1507],{},[1480,1493,1494,1495,1497,1498],{},"string ",[136,1496,1437],{}," \u002F ",[136,1499,1500],{},"maxLength",[1480,1502,1503,1497,1505],{},[136,1504,1437],{},[136,1506,1500],{},[1480,1508,1509,1510,1438,1513,1516],{},"the bound (",[136,1511,1512],{},"2",[136,1514,1515],{},"60",")",[1457,1518,1519,1523,1527],{},[1480,1520,1494,1521],{},[136,1522,1441],{},[1480,1524,1525],{},[136,1526,1441],{},[1480,1528,1489],{},[1457,1530,1531,1539,1545],{},[1480,1532,1533,1534,1497,1536],{},"number ",[136,1535,1444],{},[136,1537,1538],{},"max",[1480,1540,1541,1497,1543],{},[136,1542,1444],{},[136,1544,1538],{},[1480,1546,1547],{},"the bound",[1457,1549,1550,1558,1564],{},[1480,1551,1533,1552,1497,1555],{},[136,1553,1554],{},"lt",[136,1556,1557],{},"gt",[1480,1559,1560,1497,1562],{},[136,1561,1554],{},[136,1563,1557],{},[1480,1565,1547],{},[1457,1567,1568,1573,1577],{},[1480,1569,1533,1570],{},[136,1571,1572],{},"integer",[1480,1574,1575],{},[136,1576,1572],{},[1480,1578,1579],{},[136,1580,1581],{},"true",[1457,1583,1584,1593,1599],{},[1480,1585,1586,1587,1497,1590],{},"date\u002Ftime ",[136,1588,1589],{},"date",[136,1591,1592],{},"time",[1480,1594,1595,1497,1597],{},[136,1596,1589],{},[136,1598,1592],{},[1480,1600,1489],{},[1457,1602,1603,1609,1614],{},[1480,1604,1605,1608],{},[136,1606,1607],{},"uuid"," version",[1480,1610,1611],{},[136,1612,1613],{},"version",[1480,1615,1616],{},[136,1617,1618],{},"'4'",[133,1620,1621,1624,1625,1628,1629,1631,1632,1497,1634,1636],{},[141,1622,1623],{},"You only get the keys your type allows."," A plain ",[136,1626,1627],{},"name: string"," can only fail as ",[136,1630,1448],{},". You get ",[136,1633,1437],{},[136,1635,1500],{}," because the field declares those rules. The richer the type, the richer the messages you can write.",[1638,1639,1640,1641,1644,1645,144,1647,1649,1650,1653],"note",{},"Errors ",[141,1642,1643],{},"accumulate",". A value that violates both ",[136,1646,1437],{},[136,1648,1441],{}," produces two failures, not one, so the data form yields ",[141,1651,1652],{},"one message per violated constraint"," (a list). To join them into a single sentence, reach for the function escape hatch below.",[155,1655,1657],{"id":1656},"the-placeholder-dsl","The placeholder DSL",[133,1659,1660,1661,1664],{},"Templates are plain strings with ",[136,1662,1663],{},"$[…]"," tokens the renderer substitutes and the compiler validates:",[1451,1666,1667,1677],{},[1454,1668,1669],{},[1457,1670,1671,1674],{},[1460,1672,1673],{},"Token",[1460,1675,1676],{},"Resolves to",[1475,1678,1679,1693,1708,1721],{},[1457,1680,1681,1686],{},[1480,1682,1683],{},[136,1684,1685],{},"$[label]",[1480,1687,1688,1689,1692],{},"the node's ",[136,1690,1691],{},"$label",", falling back to the raw field name",[1457,1694,1695,1699],{},[1480,1696,1697],{},[136,1698,1472],{},[1480,1700,1701,1702,1704,1705,1516],{},"the failed constraint's bound (e.g. ",[136,1703,1512],{}," for ",[136,1706,1707],{},"minLength: 2",[1457,1709,1710,1715],{},[1480,1711,1712],{},[136,1713,1714],{},"$[path]",[1480,1716,1717,1718,1516],{},"the dotted path to the field (",[136,1719,1720],{},"profile.email",[1457,1722,1723,1728],{},[1480,1724,1725],{},[136,1726,1727],{},"$[index]",[1480,1729,1730,1731,1733],{},"the array element index, for ",[136,1732,1422],{}," failures",[1638,1735,1736,1739,1740,1743],{},[136,1737,1738],{},"$[value]"," (the ",[171,1741,1742],{},"actual received value",") is out of scope for v1: the error carries no input value, so threading it into the renderer is deferred.",[155,1745,1747],{"id":1746},"the-function-escape-hatch","The function escape hatch",[133,1749,1750,1751,1753,1754,1757,1758,1761],{},"Any ",[136,1752,1433],{}," entry may be an ",[141,1755,1756],{},"inline arrow"," instead of a template record, for logic the data form can't express, such as joining constraints, pluralization, or i18n lookups. It receives a synthesized ",[136,1759,1760],{},"failed"," bag (this field's failures, grouped and keyed by the same constraint names), so one call yields one message per field:",[190,1763,1765],{"className":192,"code":1764,"language":195,"meta":196,"style":196},"name: {\n  $label: 'Full name',\n  $errors: (failed) => {\n    const parts: string[] = [];\n    if (failed.minLength) parts.push(`at least ${failed.minLength.val} characters`);\n    if (failed.maxLength) parts.push(`at most ${failed.maxLength.val} characters`);\n    return parts.length ? `Name must be ${parts.join(' and ')}` : 'Invalid name';\n  },\n},\n",[136,1766,1767,1776,1790,1810,1833,1893,1942,1997,2001],{"__ignoreMap":196},[200,1768,1769,1772,1774],{"class":202,"line":203},[200,1770,1771],{"class":264},"name",[200,1773,278],{"class":213},[200,1775,268],{"class":213},[200,1777,1778,1780,1782,1784,1786,1788],{"class":202,"line":240},[200,1779,548],{"class":264},[200,1781,278],{"class":213},[200,1783,227],{"class":213},[200,1785,1048],{"class":230},[200,1787,234],{"class":213},[200,1789,1025],{"class":213},[200,1791,1792,1795,1797,1800,1803,1805,1808],{"class":202,"line":247},[200,1793,1794],{"class":264},"  $errors",[200,1796,278],{"class":213},[200,1798,1799],{"class":213}," (",[200,1801,1760],{"class":1802},"sHdIc",[200,1804,1516],{"class":213},[200,1806,1807],{"class":260}," =>",[200,1809,268],{"class":213},[200,1811,1812,1815,1818,1820,1822,1825,1828,1831],{"class":202,"line":254},[200,1813,1814],{"class":260},"    const",[200,1816,1817],{"class":220}," parts",[200,1819,278],{"class":213},[200,1821,374],{"class":264},[200,1823,1824],{"class":274},"[] ",[200,1826,1827],{"class":213},"=",[200,1829,1830],{"class":274}," []",[200,1832,237],{"class":213},[200,1834,1835,1838,1840,1842,1844,1846,1849,1852,1854,1858,1861,1864,1867,1870,1872,1874,1876,1878,1881,1884,1887,1889,1891],{"class":202,"line":271},[200,1836,1837],{"class":206},"    if",[200,1839,1799],{"class":274},[200,1841,1760],{"class":220},[200,1843,284],{"class":213},[200,1845,1437],{"class":220},[200,1847,1848],{"class":274},") ",[200,1850,1851],{"class":220},"parts",[200,1853,284],{"class":213},[200,1855,1857],{"class":1856},"s2Zo4","push",[200,1859,1860],{"class":274},"(",[200,1862,1863],{"class":213},"`",[200,1865,1866],{"class":230},"at least ",[200,1868,1869],{"class":213},"${",[200,1871,1760],{"class":220},[200,1873,284],{"class":213},[200,1875,1437],{"class":220},[200,1877,284],{"class":213},[200,1879,1880],{"class":220},"val",[200,1882,1883],{"class":213},"}",[200,1885,1886],{"class":230}," characters",[200,1888,1863],{"class":213},[200,1890,1516],{"class":274},[200,1892,237],{"class":213},[200,1894,1895,1897,1899,1901,1903,1905,1907,1909,1911,1913,1915,1917,1920,1922,1924,1926,1928,1930,1932,1934,1936,1938,1940],{"class":202,"line":316},[200,1896,1837],{"class":206},[200,1898,1799],{"class":274},[200,1900,1760],{"class":220},[200,1902,284],{"class":213},[200,1904,1500],{"class":220},[200,1906,1848],{"class":274},[200,1908,1851],{"class":220},[200,1910,284],{"class":213},[200,1912,1857],{"class":1856},[200,1914,1860],{"class":274},[200,1916,1863],{"class":213},[200,1918,1919],{"class":230},"at most ",[200,1921,1869],{"class":213},[200,1923,1760],{"class":220},[200,1925,284],{"class":213},[200,1927,1500],{"class":220},[200,1929,284],{"class":213},[200,1931,1880],{"class":220},[200,1933,1883],{"class":213},[200,1935,1886],{"class":230},[200,1937,1863],{"class":213},[200,1939,1516],{"class":274},[200,1941,237],{"class":213},[200,1943,1944,1947,1949,1951,1954,1957,1960,1963,1965,1967,1969,1972,1974,1976,1978,1980,1982,1985,1988,1990,1993,1995],{"class":202,"line":353},[200,1945,1946],{"class":206},"    return",[200,1948,1817],{"class":220},[200,1950,284],{"class":213},[200,1952,1953],{"class":220},"length",[200,1955,1956],{"class":213}," ?",[200,1958,1959],{"class":213}," `",[200,1961,1962],{"class":230},"Name must be ",[200,1964,1869],{"class":213},[200,1966,1851],{"class":220},[200,1968,284],{"class":213},[200,1970,1971],{"class":1856},"join",[200,1973,1860],{"class":220},[200,1975,234],{"class":213},[200,1977,144],{"class":230},[200,1979,234],{"class":213},[200,1981,1516],{"class":220},[200,1983,1984],{"class":213},"}`",[200,1986,1987],{"class":213}," :",[200,1989,227],{"class":213},[200,1991,1992],{"class":230},"Invalid name",[200,1994,234],{"class":213},[200,1996,237],{"class":213},[200,1998,1999],{"class":202,"line":366},[200,2000,645],{"class":213},[200,2002,2003],{"class":202,"line":382},[200,2004,2005],{"class":213},"},\n",[133,2007,2008,2009,2012],{},"The function must be an ",[141,2010,2011],{},"inline"," expression (no external reference); its body runs at runtime, so it can call i18n machinery freely. The trade-off: the data form gets compile-time placeholder and constraint validation; a function doesn't.",[155,2014,2016,2017],{"id":2015},"rendering-at-runtime-with-createfriendly","Rendering at runtime with ",[136,2018,2019],{},"createFriendly",[133,2021,2022,2023,2026],{},"Rendering needs nothing but the map and the errors. ",[136,2024,2025],{},"createFriendly\u003CT>(map)"," returns a renderer with two methods:",[190,2028,2030],{"className":192,"code":2029,"language":195,"meta":196,"style":196},"import { createFriendly } from 'ts-runtypes';\nimport { userFriendly } from 'runtypes\u002Fgenerated\u002Fmodels\u002Fuser';\n\nconst friendly = createFriendly\u003CUser>(userFriendly);\n\n\u002F\u002F label(path): dotted string or a raw path-segment array\nfriendly.label('profile.email');\n\u002F\u002F → 'Email'\n\n\u002F\u002F errors(errs): render a createGetValidationErrors result into messages\nfriendly.errors(getUserErrors(badInput));\n\u002F\u002F → [{ path: 'profile.email', label: 'Email', message: 'Enter a valid email address' }]\n",[136,2031,2032,2053,2074,2078,2101,2105,2110,2131,2136,2140,2145,2164],{"__ignoreMap":196},[200,2033,2034,2036,2038,2041,2043,2045,2047,2049,2051],{"class":202,"line":203},[200,2035,207],{"class":206},[200,2037,466],{"class":213},[200,2039,2040],{"class":220}," createFriendly",[200,2042,472],{"class":213},[200,2044,475],{"class":206},[200,2046,227],{"class":213},[200,2048,480],{"class":230},[200,2050,234],{"class":213},[200,2052,237],{"class":213},[200,2054,2055,2057,2059,2061,2063,2065,2067,2070,2072],{"class":202,"line":240},[200,2056,207],{"class":206},[200,2058,466],{"class":213},[200,2060,526],{"class":220},[200,2062,472],{"class":213},[200,2064,475],{"class":206},[200,2066,227],{"class":213},[200,2068,2069],{"class":230},"runtypes\u002Fgenerated\u002Fmodels\u002Fuser",[200,2071,234],{"class":213},[200,2073,237],{"class":213},[200,2075,2076],{"class":202,"line":247},[200,2077,244],{"emptyLinePlaceholder":243},[200,2079,2080,2083,2086,2088,2090,2092,2094,2096,2099],{"class":202,"line":254},[200,2081,2082],{"class":260},"const",[200,2084,2085],{"class":220}," friendly ",[200,2087,1827],{"class":213},[200,2089,2040],{"class":1856},[200,2091,533],{"class":213},[200,2093,184],{"class":264},[200,2095,538],{"class":213},[200,2097,2098],{"class":220},"(userFriendly)",[200,2100,237],{"class":213},[200,2102,2103],{"class":202,"line":271},[200,2104,244],{"emptyLinePlaceholder":243},[200,2106,2107],{"class":202,"line":316},[200,2108,2109],{"class":250},"\u002F\u002F label(path): dotted string or a raw path-segment array\n",[200,2111,2112,2115,2117,2119,2121,2123,2125,2127,2129],{"class":202,"line":353},[200,2113,2114],{"class":220},"friendly",[200,2116,284],{"class":213},[200,2118,143],{"class":1856},[200,2120,1860],{"class":220},[200,2122,234],{"class":213},[200,2124,1720],{"class":230},[200,2126,234],{"class":213},[200,2128,1516],{"class":220},[200,2130,237],{"class":213},[200,2132,2133],{"class":202,"line":366},[200,2134,2135],{"class":250},"\u002F\u002F → 'Email'\n",[200,2137,2138],{"class":202,"line":382},[200,2139,244],{"emptyLinePlaceholder":243},[200,2141,2142],{"class":202,"line":392},[200,2143,2144],{"class":250},"\u002F\u002F errors(errs): render a createGetValidationErrors result into messages\n",[200,2146,2147,2149,2151,2154,2156,2159,2162],{"class":202,"line":409},[200,2148,2114],{"class":220},[200,2150,284],{"class":213},[200,2152,2153],{"class":1856},"errors",[200,2155,1860],{"class":220},[200,2157,2158],{"class":1856},"getUserErrors",[200,2160,2161],{"class":220},"(badInput))",[200,2163,237],{"class":213},[200,2165,2166],{"class":202,"line":442},[200,2167,2168],{"class":250},"\u002F\u002F → [{ path: 'profile.email', label: 'Email', message: 'Enter a valid email address' }]\n",[133,2170,2171,2174,2175,2178,2179,2181,2182,278],{},[136,2172,2173],{},"errors()"," groups failures by path, walks each ",[136,2176,2177],{},"path"," into the map, picks the template for the failed constraint, and fills in the ",[136,2180,1663],{}," tokens. Each result is a ",[136,2183,2184],{},"FriendlyMessage",[190,2186,2188],{"className":192,"code":2187,"language":195,"meta":196,"style":196},"interface FriendlyMessage {\n  path: string;     \u002F\u002F dotted path to the field ('profile.email'); '' for the root\n  label: string;    \u002F\u002F the field's $label, or its raw last path segment as fallback\n  message: string;  \u002F\u002F the interpolated message\n}\n",[136,2189,2190,2200,2214,2228,2242],{"__ignoreMap":196},[200,2191,2192,2195,2198],{"class":202,"line":203},[200,2193,2194],{"class":260},"interface",[200,2196,2197],{"class":264}," FriendlyMessage",[200,2199,268],{"class":213},[200,2201,2202,2205,2207,2209,2211],{"class":202,"line":240},[200,2203,2204],{"class":274},"  path",[200,2206,278],{"class":213},[200,2208,374],{"class":264},[200,2210,302],{"class":213},[200,2212,2213],{"class":250},"     \u002F\u002F dotted path to the field ('profile.email'); '' for the root\n",[200,2215,2216,2219,2221,2223,2225],{"class":202,"line":247},[200,2217,2218],{"class":274},"  label",[200,2220,278],{"class":213},[200,2222,374],{"class":264},[200,2224,302],{"class":213},[200,2226,2227],{"class":250},"    \u002F\u002F the field's $label, or its raw last path segment as fallback\n",[200,2229,2230,2233,2235,2237,2239],{"class":202,"line":254},[200,2231,2232],{"class":274},"  message",[200,2234,278],{"class":213},[200,2236,374],{"class":264},[200,2238,302],{"class":213},[200,2240,2241],{"class":250},"  \u002F\u002F the interpolated message\n",[200,2243,2244],{"class":202,"line":271},[200,2245,451],{"class":213},[133,2247,2248,2249,2251,2252,2254],{},"A data-form ",[136,2250,1433],{}," yields one message per violated constraint; a function-form ",[136,2253,1433],{}," yields one message per field. When a field has no map entry, the renderer falls back gracefully, using the raw field name as the label and a generic \"is invalid\" message.",[1638,2256,2257,2258,2261],{},"Error rendering works today. ",[141,2259,2260],{},"Form-building UI is coming later."," Listing every field of a type to build a form needs the type's reflection data, which RunTypes already exposes; pairing the two is a small future addition.",[2263,2264,2265],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}","Human-readable labels and error messages for a type.","md",null,{"toc":18},{"title":64,"description":2266},"6XHxlYite25iBlHHWk-YOz6PtscJZptx0Yyom-GdqOk",[2273,2275],{"title":61,"path":56,"stem":62,"description":2274,"children":-1},"How AI agents and the compiler work together to enrich your types.",{"title":68,"path":69,"stem":70,"description":2276,"children":-1},"Realistic sample data for a type, checked against its fields at build time.",1781995977193]