[{"data":1,"prerenderedAt":2839},["ShallowReactive",2],{"navigation_docs":3,"-guide-json-serialization":149,"-guide-json-serialization-surround":2834},[4,27,81,103,144],{"title":5,"icon":6,"redirect":7,"path":8,"stem":9,"children":10,"page":26},"Introduction","i-lucide-rocket","\u002Fintroduction\u002Fabout-ts-runtypes","\u002Fintroduction","01.introduction",[11,14,18,22],{"title":12,"path":7,"stem":13},"About RunTypes","01.introduction\u002F01.about-ts-runtypes",{"title":15,"path":16,"stem":17},"Built on typescript-go","\u002Fintroduction\u002Fbuilt-on-typescript-go","01.introduction\u002F02.built-on-typescript-go",{"title":19,"path":20,"stem":21},"Quick Start","\u002Fintroduction\u002Fquick-start","01.introduction\u002F03.quick-start",{"title":23,"path":24,"stem":25},"Configuration","\u002Fintroduction\u002Fconfiguration","01.introduction\u002F04.configuration",false,{"title":28,"icon":29,"redirect":30,"path":31,"stem":32,"children":33,"page":26},"Guide","i-lucide-book-open","\u002Fguide\u002Ftype-builders","\u002Fguide","02.guide",[34,37,41,45,49,53,57,61,65,69,73,77],{"title":35,"path":30,"stem":36},"Types vs Type Builders","02.guide\u002F01.type-builders",{"title":38,"path":39,"stem":40},"Type Formats","\u002Fguide\u002Ftype-formats","02.guide\u002F02.type-formats",{"title":42,"path":43,"stem":44},"Validation","\u002Fguide\u002Fvalidation","02.guide\u002F03.validation",{"title":46,"path":47,"stem":48},"Reflection","\u002Fguide\u002Freflection","02.guide\u002F04.reflection",{"title":50,"path":51,"stem":52},"JSON Serialization","\u002Fguide\u002Fjson-serialization","02.guide\u002F05.json-serialization",{"title":54,"path":55,"stem":56},"Binary Serialization","\u002Fguide\u002Fbinary-serialization","02.guide\u002F06.binary-serialization",{"title":58,"path":59,"stem":60},"Data Mocking","\u002Fguide\u002Fmocking","02.guide\u002F07.mocking",{"title":62,"path":63,"stem":64},"Compiler Markers","\u002Fguide\u002Fcompiler-markers","02.guide\u002F08.compiler-markers",{"title":66,"path":67,"stem":68},"Pure Functions","\u002Fguide\u002Fpure-functions","02.guide\u002F09.pure-functions",{"title":70,"path":71,"stem":72},"Linting","\u002Fguide\u002Flinting","02.guide\u002F10.linting",{"title":74,"path":75,"stem":76},"Source Conversion","\u002Fguide\u002Fsource-conversion","02.guide\u002F13.source-conversion",{"title":78,"path":79,"stem":80},"Generating JSON Schema","\u002Fguide\u002Fjson-schema-generation","02.guide\u002F14.json-schema-generation",{"title":82,"icon":83,"redirect":84,"path":85,"stem":86,"children":87,"page":26},"AI Integration","i-lucide-sparkles","\u002Fai-integration\u002Fworkflow-and-commands","\u002Fai-integration","03.ai-integration",[88,91,95,99],{"title":89,"path":84,"stem":90},"AI Workflow","03.ai-integration\u002F01.workflow-and-commands",{"title":92,"path":93,"stem":94},"FriendlyText","\u002Fai-integration\u002Ffriendly-type","03.ai-integration\u002F02.friendly-type",{"title":96,"path":97,"stem":98},"MockData","\u002Fai-integration\u002Fmock-data","03.ai-integration\u002F03.mock-data",{"title":100,"path":101,"stem":102},"Translations (i18n)","\u002Fai-integration\u002Fi18n","03.ai-integration\u002F04.i18n",{"title":104,"icon":105,"redirect":106,"path":107,"stem":108,"children":109,"page":26},"Benchmarks","i-lucide-gauge","\u002Fbenchmarks\u002Fvalidation","\u002Fbenchmarks","07.benchmarks",[110,112,116,120,124,128,132,136,140],{"title":42,"path":106,"stem":111},"07.benchmarks\u002F01.validation",{"title":113,"path":114,"stem":115},"Validation Formats","\u002Fbenchmarks\u002Fvalidation-formats","07.benchmarks\u002F02.validation-formats",{"title":117,"path":118,"stem":119},"Validation Errors","\u002Fbenchmarks\u002Fgetvalidationerrors","07.benchmarks\u002F03.getvalidationerrors",{"title":121,"path":122,"stem":123},"Validation Error Formats","\u002Fbenchmarks\u002Fgetvalidationerrors-formats","07.benchmarks\u002F04.getvalidationerrors-formats",{"title":125,"path":126,"stem":127},"Serialization","\u002Fbenchmarks\u002Fserialization","07.benchmarks\u002F05.serialization",{"title":129,"path":130,"stem":131},"Serialization Formats","\u002Fbenchmarks\u002Fserialization-formats","07.benchmarks\u002F06.serialization-formats",{"title":133,"path":134,"stem":135},"Compile Time","\u002Fbenchmarks\u002Fcompiletime","07.benchmarks\u002F07.compiletime",{"title":137,"path":138,"stem":139},"Correctness","\u002Fbenchmarks\u002Fcorrectness","07.benchmarks\u002F08.correctness",{"title":141,"path":142,"stem":143},"Strict validation","\u002Fbenchmarks\u002Fstrict","07.benchmarks\u002F09.strict",{"title":145,"path":146,"stem":147,"icon":148},"Diagnostics","\u002Fdiagnostics","08.diagnostics","i-lucide-triangle-alert",{"id":150,"title":50,"body":151,"description":2828,"extension":2829,"links":2830,"meta":2831,"navigation":271,"path":51,"seo":2832,"stem":52,"__hash__":2833},"docs\u002F02.guide\u002F05.json-serialization.md",{"type":152,"value":153},"minimark",[154,159,175,529,535,567,576,580,590,713,722,848,852,860,1017,1020,1111,1120,1124,1145,1784,1787,1810,1813,1827,1838,1861,1868,1893,1897,1922,2061,2075,2252,2285,2291,2306,2408,2411,2420,2424,2437,2455,2459,2466,2485,2791,2800,2824],[155,156,158],"h2",{"id":157},"the-round-trip","The round trip",[160,161,162,166,167,170,171,174],"p",{},[163,164,165],"code",{},"createJsonEncoderFn"," and ",[163,168,169],{},"createJsonDecoderFn"," understand the types ",[163,172,173],{},"JSON.stringify"," can't. Because the pair is generated from your type, it knows all the types that requires transform or coercion to survive the round trip.",[176,177,182],"pre",{"className":178,"code":179,"language":180,"meta":181,"style":181},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F A type with members JSON.stringify quietly mangles: a Date and a Set.\ntype Session = {\n  id: string;\n  startedAt: Date;\n  roles: Set\u003Cstring>;\n};\n\nconst session: Session = {\n  id: 's-1',\n  startedAt: new Date('2026-01-01T00:00:00Z'),\n  roles: new Set(['admin', 'editor']),\n};\n\nconst encode = createJsonEncoderFn\u003CSession>();\nconst decode = createJsonDecoderFn\u003CSession>();\n\nconst wire = encode(session)!; \u002F\u002F a JSON string: Date and Set survive\nconst back = decode(wire); \u002F\u002F Date is a Date again, Set is a Set again\n\nback.startedAt instanceof Date; \u002F\u002F true\nback.roles instanceof Set; \u002F\u002F true\n","ts","",[163,183,184,193,211,227,240,260,266,273,291,311,339,375,380,385,412,435,440,462,484,489,511],{"__ignoreMap":181},[185,186,189],"span",{"class":187,"line":188},"line",1,[185,190,192],{"class":191},"sHwdD","\u002F\u002F A type with members JSON.stringify quietly mangles: a Date and a Set.\n",[185,194,196,200,204,208],{"class":187,"line":195},2,[185,197,199],{"class":198},"spNyl","type",[185,201,203],{"class":202},"sBMFI"," Session",[185,205,207],{"class":206},"sMK4o"," =",[185,209,210],{"class":206}," {\n",[185,212,214,218,221,224],{"class":187,"line":213},3,[185,215,217],{"class":216},"swJcz","  id",[185,219,220],{"class":206},":",[185,222,223],{"class":202}," string",[185,225,226],{"class":206},";\n",[185,228,230,233,235,238],{"class":187,"line":229},4,[185,231,232],{"class":216},"  startedAt",[185,234,220],{"class":206},[185,236,237],{"class":202}," Date",[185,239,226],{"class":206},[185,241,243,246,248,251,254,257],{"class":187,"line":242},5,[185,244,245],{"class":216},"  roles",[185,247,220],{"class":206},[185,249,250],{"class":202}," Set",[185,252,253],{"class":206},"\u003C",[185,255,256],{"class":202},"string",[185,258,259],{"class":206},">;\n",[185,261,263],{"class":187,"line":262},6,[185,264,265],{"class":206},"};\n",[185,267,269],{"class":187,"line":268},7,[185,270,272],{"emptyLinePlaceholder":271},true,"\n",[185,274,276,279,283,285,287,289],{"class":187,"line":275},8,[185,277,278],{"class":198},"const",[185,280,282],{"class":281},"sTEyZ"," session",[185,284,220],{"class":206},[185,286,203],{"class":202},[185,288,207],{"class":206},[185,290,210],{"class":206},[185,292,294,296,298,301,305,308],{"class":187,"line":293},9,[185,295,217],{"class":216},[185,297,220],{"class":206},[185,299,300],{"class":206}," '",[185,302,304],{"class":303},"sfazB","s-1",[185,306,307],{"class":206},"'",[185,309,310],{"class":206},",\n",[185,312,314,316,318,321,324,327,329,332,334,337],{"class":187,"line":313},10,[185,315,232],{"class":216},[185,317,220],{"class":206},[185,319,320],{"class":206}," new",[185,322,237],{"class":323},"s2Zo4",[185,325,326],{"class":281},"(",[185,328,307],{"class":206},[185,330,331],{"class":303},"2026-01-01T00:00:00Z",[185,333,307],{"class":206},[185,335,336],{"class":281},")",[185,338,310],{"class":206},[185,340,342,344,346,348,350,353,355,358,360,363,365,368,370,373],{"class":187,"line":341},11,[185,343,245],{"class":216},[185,345,220],{"class":206},[185,347,320],{"class":206},[185,349,250],{"class":323},[185,351,352],{"class":281},"([",[185,354,307],{"class":206},[185,356,357],{"class":303},"admin",[185,359,307],{"class":206},[185,361,362],{"class":206},",",[185,364,300],{"class":206},[185,366,367],{"class":303},"editor",[185,369,307],{"class":206},[185,371,372],{"class":281},"])",[185,374,310],{"class":206},[185,376,378],{"class":187,"line":377},12,[185,379,265],{"class":206},[185,381,383],{"class":187,"line":382},13,[185,384,272],{"emptyLinePlaceholder":271},[185,386,388,390,393,396,399,401,404,407,410],{"class":187,"line":387},14,[185,389,278],{"class":198},[185,391,392],{"class":281}," encode ",[185,394,395],{"class":206},"=",[185,397,398],{"class":323}," createJsonEncoderFn",[185,400,253],{"class":206},[185,402,403],{"class":202},"Session",[185,405,406],{"class":206},">",[185,408,409],{"class":281},"()",[185,411,226],{"class":206},[185,413,415,417,420,422,425,427,429,431,433],{"class":187,"line":414},15,[185,416,278],{"class":198},[185,418,419],{"class":281}," decode ",[185,421,395],{"class":206},[185,423,424],{"class":323}," createJsonDecoderFn",[185,426,253],{"class":206},[185,428,403],{"class":202},[185,430,406],{"class":206},[185,432,409],{"class":281},[185,434,226],{"class":206},[185,436,438],{"class":187,"line":437},16,[185,439,272],{"emptyLinePlaceholder":271},[185,441,443,445,448,450,453,456,459],{"class":187,"line":442},17,[185,444,278],{"class":198},[185,446,447],{"class":281}," wire ",[185,449,395],{"class":206},[185,451,452],{"class":323}," encode",[185,454,455],{"class":281},"(session)",[185,457,458],{"class":206},"!;",[185,460,461],{"class":191}," \u002F\u002F a JSON string: Date and Set survive\n",[185,463,465,467,470,472,475,478,481],{"class":187,"line":464},18,[185,466,278],{"class":198},[185,468,469],{"class":281}," back ",[185,471,395],{"class":206},[185,473,474],{"class":323}," decode",[185,476,477],{"class":281},"(wire)",[185,479,480],{"class":206},";",[185,482,483],{"class":191}," \u002F\u002F Date is a Date again, Set is a Set again\n",[185,485,487],{"class":187,"line":486},19,[185,488,272],{"emptyLinePlaceholder":271},[185,490,492,495,498,501,504,506,508],{"class":187,"line":491},20,[185,493,494],{"class":281},"back",[185,496,497],{"class":206},".",[185,499,500],{"class":281},"startedAt ",[185,502,503],{"class":206},"instanceof",[185,505,237],{"class":202},[185,507,480],{"class":206},[185,509,510],{"class":191}," \u002F\u002F true\n",[185,512,514,516,518,521,523,525,527],{"class":187,"line":513},21,[185,515,494],{"class":281},[185,517,497],{"class":206},[185,519,520],{"class":281},"roles ",[185,522,503],{"class":206},[185,524,250],{"class":202},[185,526,480],{"class":206},[185,528,510],{"class":191},[160,530,531,532,534],{},"Here's the same data through plain ",[163,533,173],{},", for contrast:",[176,536,538],{"className":178,"code":537,"language":180,"meta":181,"style":181},"\u002F\u002F Plain JSON.stringify can't do this: your Date turns into a string and\n\u002F\u002F your Set turns into {} on the way out, and never comes back.\nJSON.stringify(session); \u002F\u002F {\"id\":\"s-1\",\"startedAt\":\"2026-01-01T...\",\"roles\":{}}\n",[163,539,540,545,550],{"__ignoreMap":181},[185,541,542],{"class":187,"line":188},[185,543,544],{"class":191},"\u002F\u002F Plain JSON.stringify can't do this: your Date turns into a string and\n",[185,546,547],{"class":187,"line":195},[185,548,549],{"class":191},"\u002F\u002F your Set turns into {} on the way out, and never comes back.\n",[185,551,552,555,557,560,562,564],{"class":187,"line":213},[185,553,554],{"class":281},"JSON",[185,556,497],{"class":206},[185,558,559],{"class":323},"stringify",[185,561,455],{"class":281},[185,563,480],{"class":206},[185,565,566],{"class":191}," \u002F\u002F {\"id\":\"s-1\",\"startedAt\":\"2026-01-01T...\",\"roles\":{}}\n",[568,569,570,571,166,573,497],"note",{},"The generated code is highly optimised. When a type needs no custom encoding or decoding, nothing is generated at all and the call is equal to the native ",[163,572,173],{},[163,574,575],{},"JSON.parse",[155,577,579],{"id":578},"using-the-two-factories","Using the two factories",[160,581,582,585,586,589],{},[163,583,584],{},"createJsonEncoderFn\u003CT>()"," returns a function that turns a ",[163,587,588],{},"T"," into a JSON string. Call the factory once per type, next to the type itself, and reuse the function you get back.",[176,591,593],{"className":178,"code":592,"language":180,"meta":181,"style":181},"\u002F\u002F One call per type, at module level: the encoder is compiled at build time.\nconst encodeUser = createJsonEncoderFn\u003CUser>();\n\nconst json = encodeUser(user); \u002F\u002F a JSON string, or undefined if you pass undefined\n\n\u002F\u002F The second argument is the options bag. `strategy` picks how the value is\n\u002F\u002F walked, `mutate` being the fastest when you don't mind the input changing.\nconst encodeFast = createJsonEncoderFn\u003CUser>(undefined, {strategy: 'mutate'});\nencodeFast(user);\n",[163,594,595,600,622,626,646,650,655,660,704],{"__ignoreMap":181},[185,596,597],{"class":187,"line":188},[185,598,599],{"class":191},"\u002F\u002F One call per type, at module level: the encoder is compiled at build time.\n",[185,601,602,604,607,609,611,613,616,618,620],{"class":187,"line":195},[185,603,278],{"class":198},[185,605,606],{"class":281}," encodeUser ",[185,608,395],{"class":206},[185,610,398],{"class":323},[185,612,253],{"class":206},[185,614,615],{"class":202},"User",[185,617,406],{"class":206},[185,619,409],{"class":281},[185,621,226],{"class":206},[185,623,624],{"class":187,"line":213},[185,625,272],{"emptyLinePlaceholder":271},[185,627,628,630,633,635,638,641,643],{"class":187,"line":229},[185,629,278],{"class":198},[185,631,632],{"class":281}," json ",[185,634,395],{"class":206},[185,636,637],{"class":323}," encodeUser",[185,639,640],{"class":281},"(user)",[185,642,480],{"class":206},[185,644,645],{"class":191}," \u002F\u002F a JSON string, or undefined if you pass undefined\n",[185,647,648],{"class":187,"line":242},[185,649,272],{"emptyLinePlaceholder":271},[185,651,652],{"class":187,"line":262},[185,653,654],{"class":191},"\u002F\u002F The second argument is the options bag. `strategy` picks how the value is\n",[185,656,657],{"class":187,"line":268},[185,658,659],{"class":191},"\u002F\u002F walked, `mutate` being the fastest when you don't mind the input changing.\n",[185,661,662,664,667,669,671,673,675,677,679,682,685,688,690,692,695,697,700,702],{"class":187,"line":275},[185,663,278],{"class":198},[185,665,666],{"class":281}," encodeFast ",[185,668,395],{"class":206},[185,670,398],{"class":323},[185,672,253],{"class":206},[185,674,615],{"class":202},[185,676,406],{"class":206},[185,678,326],{"class":281},[185,680,681],{"class":206},"undefined,",[185,683,684],{"class":206}," {",[185,686,687],{"class":216},"strategy",[185,689,220],{"class":206},[185,691,300],{"class":206},[185,693,694],{"class":303},"mutate",[185,696,307],{"class":206},[185,698,699],{"class":206},"}",[185,701,336],{"class":281},[185,703,226],{"class":206},[185,705,706,709,711],{"class":187,"line":293},[185,707,708],{"class":323},"encodeFast",[185,710,640],{"class":281},[185,712,226],{"class":206},[160,714,715,718,719,497],{},[163,716,717],{},"createJsonDecoderFn\u003CT>()"," is the other half. It takes the JSON string and gives you the value back, typed as ",[163,720,721],{},"DataOnly\u003CT>",[176,723,725],{"className":178,"code":724,"language":180,"meta":181,"style":181},"\u002F\u002F The other half, built from the same type.\nconst decodeUser = createJsonDecoderFn\u003CUser>();\n\nconst back = decodeUser(json!); \u002F\u002F signedUpAt is a Date again, typed as DataOnly\u003CUser>\n\n\u002F\u002F `strategy: 'preserve'` keeps properties your type doesn't declare,\n\u002F\u002F the default `strip` drops them.\nconst decodeLoose = createJsonDecoderFn\u003CUser>(undefined, {strategy: 'preserve'});\ndecodeLoose(json!);\n",[163,726,727,732,753,757,781,785,790,795,835],{"__ignoreMap":181},[185,728,729],{"class":187,"line":188},[185,730,731],{"class":191},"\u002F\u002F The other half, built from the same type.\n",[185,733,734,736,739,741,743,745,747,749,751],{"class":187,"line":195},[185,735,278],{"class":198},[185,737,738],{"class":281}," decodeUser ",[185,740,395],{"class":206},[185,742,424],{"class":323},[185,744,253],{"class":206},[185,746,615],{"class":202},[185,748,406],{"class":206},[185,750,409],{"class":281},[185,752,226],{"class":206},[185,754,755],{"class":187,"line":213},[185,756,272],{"emptyLinePlaceholder":271},[185,758,759,761,763,765,768,771,774,776,778],{"class":187,"line":229},[185,760,278],{"class":198},[185,762,469],{"class":281},[185,764,395],{"class":206},[185,766,767],{"class":323}," decodeUser",[185,769,770],{"class":281},"(json",[185,772,773],{"class":206},"!",[185,775,336],{"class":281},[185,777,480],{"class":206},[185,779,780],{"class":191}," \u002F\u002F signedUpAt is a Date again, typed as DataOnly\u003CUser>\n",[185,782,783],{"class":187,"line":242},[185,784,272],{"emptyLinePlaceholder":271},[185,786,787],{"class":187,"line":262},[185,788,789],{"class":191},"\u002F\u002F `strategy: 'preserve'` keeps properties your type doesn't declare,\n",[185,791,792],{"class":187,"line":268},[185,793,794],{"class":191},"\u002F\u002F the default `strip` drops them.\n",[185,796,797,799,802,804,806,808,810,812,814,816,818,820,822,824,827,829,831,833],{"class":187,"line":275},[185,798,278],{"class":198},[185,800,801],{"class":281}," decodeLoose ",[185,803,395],{"class":206},[185,805,424],{"class":323},[185,807,253],{"class":206},[185,809,615],{"class":202},[185,811,406],{"class":206},[185,813,326],{"class":281},[185,815,681],{"class":206},[185,817,684],{"class":206},[185,819,687],{"class":216},[185,821,220],{"class":206},[185,823,300],{"class":206},[185,825,826],{"class":303},"preserve",[185,828,307],{"class":206},[185,830,699],{"class":206},[185,832,336],{"class":281},[185,834,226],{"class":206},[185,836,837,840,842,844,846],{"class":187,"line":293},[185,838,839],{"class":323},"decodeLoose",[185,841,770],{"class":281},[185,843,773],{"class":206},[185,845,336],{"class":281},[185,847,226],{"class":206},[155,849,851],{"id":850},"three-encoder-strategies","Three encoder strategies",[160,853,854,856,857,859],{},[163,855,165],{}," takes a ",[163,858,687],{}," (a call-site literal) that decides how it walks your value and what it does with undeclared keys.",[176,861,863],{"className":178,"code":862,"language":180,"meta":181,"style":181},"\u002F\u002F 'clone' (default): builds a fresh value from the declared shape, so\n\u002F\u002F undeclared keys are dropped for free. Never touches your input.\nconst encodeClean = createJsonEncoderFn\u003CProfile>(undefined, {strategy: 'clone'});\n\n\u002F\u002F 'mutate': transforms leaves in place (no clone), and KEEPS undeclared keys\n\u002F\u002F on the wire. Fastest, but it mutates the object you pass in.\nconst encodeFast = createJsonEncoderFn\u003CProfile>(undefined, {strategy: 'mutate'});\n\n\u002F\u002F 'direct': single pass, no clone, always strips undeclared keys.\nconst encodeDirect = createJsonEncoderFn\u003CProfile>(undefined, {strategy: 'direct'});\n",[163,864,865,870,875,916,920,925,930,968,972,977],{"__ignoreMap":181},[185,866,867],{"class":187,"line":188},[185,868,869],{"class":191},"\u002F\u002F 'clone' (default): builds a fresh value from the declared shape, so\n",[185,871,872],{"class":187,"line":195},[185,873,874],{"class":191},"\u002F\u002F undeclared keys are dropped for free. Never touches your input.\n",[185,876,877,879,882,884,886,888,891,893,895,897,899,901,903,905,908,910,912,914],{"class":187,"line":213},[185,878,278],{"class":198},[185,880,881],{"class":281}," encodeClean ",[185,883,395],{"class":206},[185,885,398],{"class":323},[185,887,253],{"class":206},[185,889,890],{"class":202},"Profile",[185,892,406],{"class":206},[185,894,326],{"class":281},[185,896,681],{"class":206},[185,898,684],{"class":206},[185,900,687],{"class":216},[185,902,220],{"class":206},[185,904,300],{"class":206},[185,906,907],{"class":303},"clone",[185,909,307],{"class":206},[185,911,699],{"class":206},[185,913,336],{"class":281},[185,915,226],{"class":206},[185,917,918],{"class":187,"line":229},[185,919,272],{"emptyLinePlaceholder":271},[185,921,922],{"class":187,"line":242},[185,923,924],{"class":191},"\u002F\u002F 'mutate': transforms leaves in place (no clone), and KEEPS undeclared keys\n",[185,926,927],{"class":187,"line":262},[185,928,929],{"class":191},"\u002F\u002F on the wire. Fastest, but it mutates the object you pass in.\n",[185,931,932,934,936,938,940,942,944,946,948,950,952,954,956,958,960,962,964,966],{"class":187,"line":268},[185,933,278],{"class":198},[185,935,666],{"class":281},[185,937,395],{"class":206},[185,939,398],{"class":323},[185,941,253],{"class":206},[185,943,890],{"class":202},[185,945,406],{"class":206},[185,947,326],{"class":281},[185,949,681],{"class":206},[185,951,684],{"class":206},[185,953,687],{"class":216},[185,955,220],{"class":206},[185,957,300],{"class":206},[185,959,694],{"class":303},[185,961,307],{"class":206},[185,963,699],{"class":206},[185,965,336],{"class":281},[185,967,226],{"class":206},[185,969,970],{"class":187,"line":275},[185,971,272],{"emptyLinePlaceholder":271},[185,973,974],{"class":187,"line":293},[185,975,976],{"class":191},"\u002F\u002F 'direct': single pass, no clone, always strips undeclared keys.\n",[185,978,979,981,984,986,988,990,992,994,996,998,1000,1002,1004,1006,1009,1011,1013,1015],{"class":187,"line":313},[185,980,278],{"class":198},[185,982,983],{"class":281}," encodeDirect ",[185,985,395],{"class":206},[185,987,398],{"class":323},[185,989,253],{"class":206},[185,991,890],{"class":202},[185,993,406],{"class":206},[185,995,326],{"class":281},[185,997,681],{"class":206},[185,999,684],{"class":206},[185,1001,687],{"class":216},[185,1003,220],{"class":206},[185,1005,300],{"class":206},[185,1007,1008],{"class":303},"direct",[185,1010,307],{"class":206},[185,1012,699],{"class":206},[185,1014,336],{"class":281},[185,1016,226],{"class":206},[160,1018,1019],{},"Each one compiles to a different specialized function. The JSON that comes out is the same, but the work behind it is very different:",[1021,1022,1023,1042],"table",{},[1024,1025,1026],"thead",{},[1027,1028,1029,1033,1036,1039],"tr",{},[1030,1031,1032],"th",{},"Strategy",[1030,1034,1035],{},"Under the hood",[1030,1037,1038],{},"Mutates input?",[1030,1040,1041],{},"Undeclared keys",[1043,1044,1045,1066,1092],"tbody",{},[1027,1046,1047,1057,1060,1063],{},[1048,1049,1050,1052,1053],"td",{},[163,1051,907],{}," ",[1054,1055,1056],"em",{},"(default)",[1048,1058,1059],{},"Builds a fresh, JSON-safe value from the declared shape, then encodes that. It's safe and never touches your input, but cloning every object costs a little more memory.",[1048,1061,1062],{},"No",[1048,1064,1065],{},"Dropped (for free)",[1027,1067,1068,1072,1083,1089],{},[1048,1069,1070],{},[163,1071,694],{},[1048,1073,1074,1075,1078,1079,1082],{},"Rewrites non-serializable leaves (",[163,1076,1077],{},"Date",", ",[163,1080,1081],{},"BigInt",", …) in place to make the value JSON-ready, then encodes it. Way faster with zero allocation, at the cost of mutating the object you pass in.",[1048,1084,1085],{},[1086,1087,1088],"strong",{},"Yes",[1048,1090,1091],{},"Kept on the wire",[1027,1093,1094,1098,1106,1108],{},[1048,1095,1096],{},[163,1097,1008],{},[1048,1099,1100,1101,1103,1104,497],{},"A purpose-built ",[163,1102,173],{},": one pass that iterates every field and writes valid JSON straight out. No clone, so it's lighter on memory than ",[163,1105,907],{},[1048,1107,1062],{},[1048,1109,1110],{},"Dropped",[1112,1113,1114,1116,1117,1119],"tip",{},[163,1115,907],{}," is the safe default. It never touches your input and drops stray keys by building a fresh value from the type. Reach for ",[163,1118,694],{}," only in a hot path where the allocation shows up in a profile, and you're fine mutating the object you pass in.",[155,1121,1123],{"id":1122},"custom-class-serializers","Custom class serializers",[160,1125,1126,1127,1078,1129,1078,1132,1078,1135,1138,1139,1144],{},"Plain objects are handled for you, and the built-in classes (",[163,1128,1077],{},[163,1130,1131],{},"Map",[163,1133,1134],{},"Set",[163,1136,1137],{},"RegExp",") round-trip for free. Your own class is different. A plain object is pure data: everything it carries survives JSON and comes back the same. A class instance is not. Its methods and getters live on the prototype (they are code, so they never ride the wire), its constructor runs real logic, and it may hold values that cannot be serialized at all. So the wire can only carry the data of an instance; turning that data back into a live object needs code the build tool does not have. That is what you register once with ",[1086,1140,1141],{},[163,1142,1143],{},"registerClassSerializer",": you hand it the class itself and (when needed) how to rebuild an instance.",[176,1146,1148],{"className":178,"code":1147,"language":180,"meta":181,"style":181},"import {registerClassSerializer, createJsonEncoderFn, createJsonDecoderFn, type DataOnly} from '@ts-runtypes\u002Fcore';\n\n\u002F\u002F A class with a non-empty constructor. The data goes on the wire structurally\n\u002F\u002F (just its declared properties), so you only have to teach ts-runtypes how to\n\u002F\u002F build a real instance back: pass the class itself and a `deserialize`.\n\u002F\u002F `serialize` is optional here (the default structural encode is exactly right).\nclass Money {\n  constructor(\n    public amount: number,\n    public currency: string\n  ) {}\n  format(): string {\n    return `${(this.amount \u002F 100).toFixed(2)} ${this.currency}`;\n  }\n}\n\nregisterClassSerializer(Money, {\n  \u002F\u002F `data` is the data-only projection (methods already gone) -> a real instance\n  deserialize: (data: DataOnly\u003CMoney>) => new Money(data.amount, data.currency),\n});\n\n\u002F\u002F A class with a zero-argument constructor. There is nothing else to supply:\n\u002F\u002F the client just hands over the class. Decode rebuilds it with `new Settings()`\n\u002F\u002F and copies the decoded properties over.\nclass Settings {\n  theme = 'light';\n  fontSize = 12;\n  summary(): string {\n    return `${this.theme}\u002F${this.fontSize}`;\n  }\n}\n\nregisterClassSerializer(Settings);\n\ntype Account = {id: string; balance: Money; settings: Settings};\n\nconst encode = createJsonEncoderFn\u003CAccount>();\nconst decode = createJsonDecoderFn\u003CAccount>();\n\nconst json = encode({id: 'acc_1', balance: new Money(4999, 'USD'), settings: new Settings()})!;\nconst back = decode(json); \u002F\u002F back.balance is a real Money, back.settings a real Settings\n\nexport {Money, Settings, encode, decode, back};\nexport type {Account};\n",[163,1149,1150,1190,1194,1199,1204,1209,1214,1224,1232,1248,1260,1268,1280,1332,1337,1342,1346,1357,1362,1414,1422,1426,1432,1438,1444,1454,1471,1484,1496,1524,1529,1534,1539,1549,1554,1593,1598,1620,1641,1646,1718,1737,1742,1771],{"__ignoreMap":181},[185,1151,1152,1156,1158,1160,1162,1164,1166,1168,1170,1173,1176,1178,1181,1183,1186,1188],{"class":187,"line":188},[185,1153,1155],{"class":1154},"s7zQu","import",[185,1157,684],{"class":206},[185,1159,1143],{"class":281},[185,1161,362],{"class":206},[185,1163,398],{"class":281},[185,1165,362],{"class":206},[185,1167,424],{"class":281},[185,1169,362],{"class":206},[185,1171,1172],{"class":1154}," type",[185,1174,1175],{"class":281}," DataOnly",[185,1177,699],{"class":206},[185,1179,1180],{"class":1154}," from",[185,1182,300],{"class":206},[185,1184,1185],{"class":303},"@ts-runtypes\u002Fcore",[185,1187,307],{"class":206},[185,1189,226],{"class":206},[185,1191,1192],{"class":187,"line":195},[185,1193,272],{"emptyLinePlaceholder":271},[185,1195,1196],{"class":187,"line":213},[185,1197,1198],{"class":191},"\u002F\u002F A class with a non-empty constructor. The data goes on the wire structurally\n",[185,1200,1201],{"class":187,"line":229},[185,1202,1203],{"class":191},"\u002F\u002F (just its declared properties), so you only have to teach ts-runtypes how to\n",[185,1205,1206],{"class":187,"line":242},[185,1207,1208],{"class":191},"\u002F\u002F build a real instance back: pass the class itself and a `deserialize`.\n",[185,1210,1211],{"class":187,"line":262},[185,1212,1213],{"class":191},"\u002F\u002F `serialize` is optional here (the default structural encode is exactly right).\n",[185,1215,1216,1219,1222],{"class":187,"line":268},[185,1217,1218],{"class":198},"class",[185,1220,1221],{"class":202}," Money",[185,1223,210],{"class":206},[185,1225,1226,1229],{"class":187,"line":275},[185,1227,1228],{"class":198},"  constructor",[185,1230,1231],{"class":206},"(\n",[185,1233,1234,1237,1241,1243,1246],{"class":187,"line":293},[185,1235,1236],{"class":198},"    public",[185,1238,1240],{"class":1239},"sHdIc"," amount",[185,1242,220],{"class":206},[185,1244,1245],{"class":202}," number",[185,1247,310],{"class":206},[185,1249,1250,1252,1255,1257],{"class":187,"line":313},[185,1251,1236],{"class":198},[185,1253,1254],{"class":1239}," currency",[185,1256,220],{"class":206},[185,1258,1259],{"class":202}," string\n",[185,1261,1262,1265],{"class":187,"line":341},[185,1263,1264],{"class":206},"  )",[185,1266,1267],{"class":206}," {}\n",[185,1269,1270,1273,1276,1278],{"class":187,"line":377},[185,1271,1272],{"class":216},"  format",[185,1274,1275],{"class":206},"():",[185,1277,223],{"class":202},[185,1279,210],{"class":206},[185,1281,1282,1285,1288,1290,1293,1296,1299,1303,1305,1307,1310,1312,1315,1317,1319,1322,1324,1327,1330],{"class":187,"line":382},[185,1283,1284],{"class":1154},"    return",[185,1286,1287],{"class":206}," `${",[185,1289,326],{"class":281},[185,1291,1292],{"class":206},"this.",[185,1294,1295],{"class":281},"amount ",[185,1297,1298],{"class":206},"\u002F",[185,1300,1302],{"class":1301},"sbssI"," 100",[185,1304,336],{"class":281},[185,1306,497],{"class":206},[185,1308,1309],{"class":323},"toFixed",[185,1311,326],{"class":281},[185,1313,1314],{"class":1301},"2",[185,1316,336],{"class":281},[185,1318,699],{"class":206},[185,1320,1321],{"class":206}," ${",[185,1323,1292],{"class":206},[185,1325,1326],{"class":281},"currency",[185,1328,1329],{"class":206},"}`",[185,1331,226],{"class":206},[185,1333,1334],{"class":187,"line":387},[185,1335,1336],{"class":206},"  }\n",[185,1338,1339],{"class":187,"line":414},[185,1340,1341],{"class":206},"}\n",[185,1343,1344],{"class":187,"line":437},[185,1345,272],{"emptyLinePlaceholder":271},[185,1347,1348,1350,1353,1355],{"class":187,"line":442},[185,1349,1143],{"class":323},[185,1351,1352],{"class":281},"(Money",[185,1354,362],{"class":206},[185,1356,210],{"class":206},[185,1358,1359],{"class":187,"line":464},[185,1360,1361],{"class":191},"  \u002F\u002F `data` is the data-only projection (methods already gone) -> a real instance\n",[185,1363,1364,1367,1369,1372,1375,1377,1379,1381,1384,1387,1390,1392,1394,1397,1399,1402,1404,1407,1409,1412],{"class":187,"line":486},[185,1365,1366],{"class":323},"  deserialize",[185,1368,220],{"class":206},[185,1370,1371],{"class":206}," (",[185,1373,1374],{"class":1239},"data",[185,1376,220],{"class":206},[185,1378,1175],{"class":202},[185,1380,253],{"class":206},[185,1382,1383],{"class":202},"Money",[185,1385,1386],{"class":206},">)",[185,1388,1389],{"class":198}," =>",[185,1391,320],{"class":206},[185,1393,1221],{"class":323},[185,1395,1396],{"class":281},"(data",[185,1398,497],{"class":206},[185,1400,1401],{"class":281},"amount",[185,1403,362],{"class":206},[185,1405,1406],{"class":281}," data",[185,1408,497],{"class":206},[185,1410,1411],{"class":281},"currency)",[185,1413,310],{"class":206},[185,1415,1416,1418,1420],{"class":187,"line":491},[185,1417,699],{"class":206},[185,1419,336],{"class":281},[185,1421,226],{"class":206},[185,1423,1424],{"class":187,"line":513},[185,1425,272],{"emptyLinePlaceholder":271},[185,1427,1429],{"class":187,"line":1428},22,[185,1430,1431],{"class":191},"\u002F\u002F A class with a zero-argument constructor. There is nothing else to supply:\n",[185,1433,1435],{"class":187,"line":1434},23,[185,1436,1437],{"class":191},"\u002F\u002F the client just hands over the class. Decode rebuilds it with `new Settings()`\n",[185,1439,1441],{"class":187,"line":1440},24,[185,1442,1443],{"class":191},"\u002F\u002F and copies the decoded properties over.\n",[185,1445,1447,1449,1452],{"class":187,"line":1446},25,[185,1448,1218],{"class":198},[185,1450,1451],{"class":202}," Settings",[185,1453,210],{"class":206},[185,1455,1457,1460,1462,1464,1467,1469],{"class":187,"line":1456},26,[185,1458,1459],{"class":216},"  theme",[185,1461,207],{"class":206},[185,1463,300],{"class":206},[185,1465,1466],{"class":303},"light",[185,1468,307],{"class":206},[185,1470,226],{"class":206},[185,1472,1474,1477,1479,1482],{"class":187,"line":1473},27,[185,1475,1476],{"class":216},"  fontSize",[185,1478,207],{"class":206},[185,1480,1481],{"class":1301}," 12",[185,1483,226],{"class":206},[185,1485,1487,1490,1492,1494],{"class":187,"line":1486},28,[185,1488,1489],{"class":216},"  summary",[185,1491,1275],{"class":206},[185,1493,223],{"class":202},[185,1495,210],{"class":206},[185,1497,1499,1501,1503,1505,1508,1510,1512,1515,1517,1520,1522],{"class":187,"line":1498},29,[185,1500,1284],{"class":1154},[185,1502,1287],{"class":206},[185,1504,1292],{"class":206},[185,1506,1507],{"class":281},"theme",[185,1509,699],{"class":206},[185,1511,1298],{"class":303},[185,1513,1514],{"class":206},"${",[185,1516,1292],{"class":206},[185,1518,1519],{"class":281},"fontSize",[185,1521,1329],{"class":206},[185,1523,226],{"class":206},[185,1525,1527],{"class":187,"line":1526},30,[185,1528,1336],{"class":206},[185,1530,1532],{"class":187,"line":1531},31,[185,1533,1341],{"class":206},[185,1535,1537],{"class":187,"line":1536},32,[185,1538,272],{"emptyLinePlaceholder":271},[185,1540,1542,1544,1547],{"class":187,"line":1541},33,[185,1543,1143],{"class":323},[185,1545,1546],{"class":281},"(Settings)",[185,1548,226],{"class":206},[185,1550,1552],{"class":187,"line":1551},34,[185,1553,272],{"emptyLinePlaceholder":271},[185,1555,1557,1559,1562,1564,1566,1569,1571,1573,1575,1578,1580,1582,1584,1587,1589,1591],{"class":187,"line":1556},35,[185,1558,199],{"class":198},[185,1560,1561],{"class":202}," Account",[185,1563,207],{"class":206},[185,1565,684],{"class":206},[185,1567,1568],{"class":216},"id",[185,1570,220],{"class":206},[185,1572,223],{"class":202},[185,1574,480],{"class":206},[185,1576,1577],{"class":216}," balance",[185,1579,220],{"class":206},[185,1581,1221],{"class":202},[185,1583,480],{"class":206},[185,1585,1586],{"class":216}," settings",[185,1588,220],{"class":206},[185,1590,1451],{"class":202},[185,1592,265],{"class":206},[185,1594,1596],{"class":187,"line":1595},36,[185,1597,272],{"emptyLinePlaceholder":271},[185,1599,1601,1603,1605,1607,1609,1611,1614,1616,1618],{"class":187,"line":1600},37,[185,1602,278],{"class":198},[185,1604,392],{"class":281},[185,1606,395],{"class":206},[185,1608,398],{"class":323},[185,1610,253],{"class":206},[185,1612,1613],{"class":202},"Account",[185,1615,406],{"class":206},[185,1617,409],{"class":281},[185,1619,226],{"class":206},[185,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639],{"class":187,"line":1622},38,[185,1624,278],{"class":198},[185,1626,419],{"class":281},[185,1628,395],{"class":206},[185,1630,424],{"class":323},[185,1632,253],{"class":206},[185,1634,1613],{"class":202},[185,1636,406],{"class":206},[185,1638,409],{"class":281},[185,1640,226],{"class":206},[185,1642,1644],{"class":187,"line":1643},39,[185,1645,272],{"emptyLinePlaceholder":271},[185,1647,1649,1651,1653,1655,1657,1659,1662,1664,1666,1668,1671,1673,1675,1677,1679,1681,1683,1685,1688,1690,1692,1695,1697,1699,1701,1703,1705,1707,1709,1711,1713,1715],{"class":187,"line":1648},40,[185,1650,278],{"class":198},[185,1652,632],{"class":281},[185,1654,395],{"class":206},[185,1656,452],{"class":323},[185,1658,326],{"class":281},[185,1660,1661],{"class":206},"{",[185,1663,1568],{"class":216},[185,1665,220],{"class":206},[185,1667,300],{"class":206},[185,1669,1670],{"class":303},"acc_1",[185,1672,307],{"class":206},[185,1674,362],{"class":206},[185,1676,1577],{"class":216},[185,1678,220],{"class":206},[185,1680,320],{"class":206},[185,1682,1221],{"class":323},[185,1684,326],{"class":281},[185,1686,1687],{"class":1301},"4999",[185,1689,362],{"class":206},[185,1691,300],{"class":206},[185,1693,1694],{"class":303},"USD",[185,1696,307],{"class":206},[185,1698,336],{"class":281},[185,1700,362],{"class":206},[185,1702,1586],{"class":216},[185,1704,220],{"class":206},[185,1706,320],{"class":206},[185,1708,1451],{"class":323},[185,1710,409],{"class":281},[185,1712,699],{"class":206},[185,1714,336],{"class":281},[185,1716,1717],{"class":206},"!;\n",[185,1719,1721,1723,1725,1727,1729,1732,1734],{"class":187,"line":1720},41,[185,1722,278],{"class":198},[185,1724,469],{"class":281},[185,1726,395],{"class":206},[185,1728,474],{"class":323},[185,1730,1731],{"class":281},"(json)",[185,1733,480],{"class":206},[185,1735,1736],{"class":191}," \u002F\u002F back.balance is a real Money, back.settings a real Settings\n",[185,1738,1740],{"class":187,"line":1739},42,[185,1741,272],{"emptyLinePlaceholder":271},[185,1743,1745,1748,1750,1752,1754,1756,1758,1760,1762,1764,1766,1769],{"class":187,"line":1744},43,[185,1746,1747],{"class":1154},"export",[185,1749,684],{"class":206},[185,1751,1383],{"class":281},[185,1753,362],{"class":206},[185,1755,1451],{"class":281},[185,1757,362],{"class":206},[185,1759,452],{"class":281},[185,1761,362],{"class":206},[185,1763,474],{"class":281},[185,1765,362],{"class":206},[185,1767,1768],{"class":281}," back",[185,1770,265],{"class":206},[185,1772,1774,1776,1778,1780,1782],{"class":187,"line":1773},44,[185,1775,1747],{"class":1154},[185,1777,1172],{"class":1154},[185,1779,684],{"class":206},[185,1781,1613],{"class":281},[185,1783,265],{"class":206},[160,1785,1786],{},"Both halves are optional:",[1788,1789,1790,1797],"ul",{},[1791,1792,1793,1796],"li",{},[163,1794,1795],{},"serialize"," defaults to the structural encode, exactly what an interface of the same shape would produce. Provide it only when you want a different wire shape (keep it to the declared properties on the JSON path).",[1791,1798,1799,1802,1803,1806,1807,1809],{},[163,1800,1801],{},"deserialize"," defaults to ",[163,1804,1805],{},"new YourClass()"," followed by copying the decoded properties over, so a class with a zero-argument constructor needs nothing but the class. Provide ",[163,1808,1801],{}," when the constructor takes arguments (the type checker requires it there).",[160,1811,1812],{},"Register before anything serializes the class.",[160,1814,1815,1816,1819,1820,166,1823,1826],{},"Generic classes need nothing extra. Generics only exist at compile time, so every instantiation of a generic class is the same class object at runtime, and one registration covers them all: register ",[163,1817,1818],{},"RpcError"," once and both ",[163,1821,1822],{},"RpcError\u003C'a'>",[163,1824,1825],{},"RpcError\u003C'b', Data>"," reconstruct from that single call. Registering the same class again just updates its handlers; it never drops coverage of an instantiation that worked before.",[160,1828,1829,1830,1833,1834,1837],{},"Classes also reconstruct inside a union. A field typed as ",[163,1831,1832],{},"Circle | Square"," comes back as the right instance, and it works even when the two classes have identical fields, because each member is picked by the actual instance. A plain object sitting next to a class in the same union (",[163,1835,1836],{},"Money | {amount: number}",") stays a plain object. You rarely think about this; it just round-trips.",[160,1839,1840,1841,166,1844,1847,1848,166,1851,1854,1855,1857,1858,497],{},"Classes extending Error keep their envelope but never leak a stack trace. The required members ",[163,1842,1843],{},"name",[163,1845,1846],{},"message"," are always serialized, so the error stays useful on the receiving side. The optional members ",[163,1849,1850],{},"stack",[163,1852,1853],{},"cause"," are guarded: they ride the wire only when the value carries them as enumerable own properties (the same test ",[163,1856,173],{}," applies), so a stack trace (which holds server file paths) never leaks by default. To include one, define it as an enumerable property on the value, for example ",[163,1859,1860],{},"Object.defineProperty(err, 'stack', {value: err.stack, enumerable: true})",[160,1862,1863,1864,1867],{},"You can opt one of your own properties into the same guard with a ",[163,1865,1866],{},"@nonEnumerable"," JSDoc tag. The tag takes effect only on an optional property, because a guarded property has to be one the type already allows to be absent. Tagging a required property does nothing (it still serializes), and a lint rule points that out.",[568,1869,1870,1871,1875,1876,1879,1880,1883,1884,1886,1887,1890,1891,497],{},"One registration covers JSON and ",[1872,1873,1874],"a",{"href":55},"binary"," alike. ",[163,1877,1878],{},"createValidateFn"," always checks a class by its structural shape and never routes through the serializer. Without a registered serializer, the build falls back to the structural shape and emits a ",[163,1881,1882],{},"CLS001"," Warning pointing you here. If the automatic ",[163,1885,1805],{}," fails because the constructor needs arguments, decode throws a ",[163,1888,1889],{},"CLS002"," error telling you to register a ",[163,1892,1801],{},[155,1894,1896],{"id":1895},"circular-references","Circular references",[160,1898,1899,1900,1903,1904,1907,1908,1910,1911,1914,1915,1918,1919,1921],{},"The generated encoders are fast precisely ",[1054,1901,1902],{},"because"," they don't track which objects they've already seen. A runtime value that points back at itself (",[163,1905,1906],{},"a.next = a",") makes them recurse until the stack overflows. ",[163,1909,165],{}," accepts a per-call ",[163,1912,1913],{},"rejectCircularRefs"," option that guards that encoder. Instead of recursing, it throws a ",[163,1916,1917],{},"CircularReferenceError"," carrying the path to the cycle, the same idea as ",[163,1920,173],{},"'s own cycle error.",[176,1923,1925],{"className":178,"code":1924,"language":180,"meta":181,"style":181},"\u002F\u002F Arm the guard for THIS encoder only. The encoder throws a\n\u002F\u002F `CircularReferenceError` instead of recursing forever.\nconst encode = createJsonEncoderFn\u003CNode>(undefined, {rejectCircularRefs: true});\n\ntry {\n  encode(cyclic as Node);\n} catch (err) {\n  err instanceof CircularReferenceError; \u002F\u002F true\n  (err as CircularReferenceError).path; \u002F\u002F ['next']: where the back-edge was found\n}\n",[163,1926,1927,1932,1937,1974,1978,1985,2005,2018,2033,2057],{"__ignoreMap":181},[185,1928,1929],{"class":187,"line":188},[185,1930,1931],{"class":191},"\u002F\u002F Arm the guard for THIS encoder only. The encoder throws a\n",[185,1933,1934],{"class":187,"line":195},[185,1935,1936],{"class":191},"\u002F\u002F `CircularReferenceError` instead of recursing forever.\n",[185,1938,1939,1941,1943,1945,1947,1949,1952,1954,1956,1958,1960,1962,1964,1968,1970,1972],{"class":187,"line":213},[185,1940,278],{"class":198},[185,1942,392],{"class":281},[185,1944,395],{"class":206},[185,1946,398],{"class":323},[185,1948,253],{"class":206},[185,1950,1951],{"class":202},"Node",[185,1953,406],{"class":206},[185,1955,326],{"class":281},[185,1957,681],{"class":206},[185,1959,684],{"class":206},[185,1961,1913],{"class":216},[185,1963,220],{"class":206},[185,1965,1967],{"class":1966},"sfNiH"," true",[185,1969,699],{"class":206},[185,1971,336],{"class":281},[185,1973,226],{"class":206},[185,1975,1976],{"class":187,"line":229},[185,1977,272],{"emptyLinePlaceholder":271},[185,1979,1980,1983],{"class":187,"line":242},[185,1981,1982],{"class":1154},"try",[185,1984,210],{"class":206},[185,1986,1987,1990,1992,1995,1998,2001,2003],{"class":187,"line":262},[185,1988,1989],{"class":323},"  encode",[185,1991,326],{"class":216},[185,1993,1994],{"class":281},"cyclic",[185,1996,1997],{"class":1154}," as",[185,1999,2000],{"class":202}," Node",[185,2002,336],{"class":216},[185,2004,226],{"class":206},[185,2006,2007,2009,2012,2015],{"class":187,"line":268},[185,2008,699],{"class":206},[185,2010,2011],{"class":1154}," catch",[185,2013,2014],{"class":281}," (err) ",[185,2016,2017],{"class":206},"{\n",[185,2019,2020,2023,2026,2029,2031],{"class":187,"line":275},[185,2021,2022],{"class":281},"  err",[185,2024,2025],{"class":206}," instanceof",[185,2027,2028],{"class":202}," CircularReferenceError",[185,2030,480],{"class":206},[185,2032,510],{"class":191},[185,2034,2035,2038,2041,2043,2045,2047,2049,2052,2054],{"class":187,"line":293},[185,2036,2037],{"class":216},"  (",[185,2039,2040],{"class":281},"err",[185,2042,1997],{"class":1154},[185,2044,2028],{"class":202},[185,2046,336],{"class":216},[185,2048,497],{"class":206},[185,2050,2051],{"class":281},"path",[185,2053,480],{"class":206},[185,2055,2056],{"class":191}," \u002F\u002F ['next']: where the back-edge was found\n",[185,2058,2059],{"class":187,"line":313},[185,2060,1341],{"class":206},[160,2062,2063,2064,2067,2068,2070,2071,2074],{},"The check is ",[1086,2065,2066],{},"pay-for-use",". ",[163,2069,1913],{}," is a compile-time option (like ",[163,2072,2073],{},"noLiterals","), so the armed factory is a separate compiled function that bakes the cycle check into its body. A plain factory for the same type carries none of it, and the walker itself is only bundled into an app that actually arms the guard somewhere. Only real cycles trigger it. A value shared between two siblings walks through fine, because the guard only watches the current path down, not every object it ever saw.",[176,2076,2078],{"className":178,"code":2077,"language":180,"meta":181,"style":181},"\u002F\u002F Shared-but-acyclic values pass: `shared` is reached twice, but never\n\u002F\u002F through itself, so the guard stays quiet.\nconst shared: Node = {name: 'shared'};\nconst dag: Node[] = [\n  {name: 'root', next: shared},\n  {name: 'alt', next: shared},\n];\n\nconst encodeList = createJsonEncoderFn\u003CNode[]>(undefined, {rejectCircularRefs: true});\nencodeList(dag); \u002F\u002F encodes normally, no cycle\n",[163,2079,2080,2085,2090,2118,2137,2165,2190,2197,2201,2239],{"__ignoreMap":181},[185,2081,2082],{"class":187,"line":188},[185,2083,2084],{"class":191},"\u002F\u002F Shared-but-acyclic values pass: `shared` is reached twice, but never\n",[185,2086,2087],{"class":187,"line":195},[185,2088,2089],{"class":191},"\u002F\u002F through itself, so the guard stays quiet.\n",[185,2091,2092,2094,2097,2099,2101,2103,2105,2107,2109,2111,2114,2116],{"class":187,"line":213},[185,2093,278],{"class":198},[185,2095,2096],{"class":281}," shared",[185,2098,220],{"class":206},[185,2100,2000],{"class":202},[185,2102,207],{"class":206},[185,2104,684],{"class":206},[185,2106,1843],{"class":216},[185,2108,220],{"class":206},[185,2110,300],{"class":206},[185,2112,2113],{"class":303},"shared",[185,2115,307],{"class":206},[185,2117,265],{"class":206},[185,2119,2120,2122,2125,2127,2129,2132,2134],{"class":187,"line":229},[185,2121,278],{"class":198},[185,2123,2124],{"class":281}," dag",[185,2126,220],{"class":206},[185,2128,2000],{"class":202},[185,2130,2131],{"class":281},"[] ",[185,2133,395],{"class":206},[185,2135,2136],{"class":281}," [\n",[185,2138,2139,2142,2144,2146,2148,2151,2153,2155,2158,2160,2162],{"class":187,"line":242},[185,2140,2141],{"class":206},"  {",[185,2143,1843],{"class":216},[185,2145,220],{"class":206},[185,2147,300],{"class":206},[185,2149,2150],{"class":303},"root",[185,2152,307],{"class":206},[185,2154,362],{"class":206},[185,2156,2157],{"class":216}," next",[185,2159,220],{"class":206},[185,2161,2096],{"class":281},[185,2163,2164],{"class":206},"},\n",[185,2166,2167,2169,2171,2173,2175,2178,2180,2182,2184,2186,2188],{"class":187,"line":262},[185,2168,2141],{"class":206},[185,2170,1843],{"class":216},[185,2172,220],{"class":206},[185,2174,300],{"class":206},[185,2176,2177],{"class":303},"alt",[185,2179,307],{"class":206},[185,2181,362],{"class":206},[185,2183,2157],{"class":216},[185,2185,220],{"class":206},[185,2187,2096],{"class":281},[185,2189,2164],{"class":206},[185,2191,2192,2195],{"class":187,"line":268},[185,2193,2194],{"class":281},"]",[185,2196,226],{"class":206},[185,2198,2199],{"class":187,"line":275},[185,2200,272],{"emptyLinePlaceholder":271},[185,2202,2203,2205,2208,2210,2212,2214,2216,2219,2221,2223,2225,2227,2229,2231,2233,2235,2237],{"class":187,"line":293},[185,2204,278],{"class":198},[185,2206,2207],{"class":281}," encodeList ",[185,2209,395],{"class":206},[185,2211,398],{"class":323},[185,2213,253],{"class":206},[185,2215,1951],{"class":202},[185,2217,2218],{"class":281},"[]",[185,2220,406],{"class":206},[185,2222,326],{"class":281},[185,2224,681],{"class":206},[185,2226,684],{"class":206},[185,2228,1913],{"class":216},[185,2230,220],{"class":206},[185,2232,1967],{"class":1966},[185,2234,699],{"class":206},[185,2236,336],{"class":281},[185,2238,226],{"class":206},[185,2240,2241,2244,2247,2249],{"class":187,"line":313},[185,2242,2243],{"class":323},"encodeList",[185,2245,2246],{"class":281},"(dag)",[185,2248,480],{"class":206},[185,2250,2251],{"class":191}," \u002F\u002F encodes normally, no cycle\n",[568,2253,2254,2255,2257,2258,2262,2263,2265,2266,2269,2270,2273,2274,166,2277,2280,2281,2284],{},"The same ",[163,2256,1913],{}," option is available on the ",[1872,2259,2261],{"href":2260},"\u002Fguide\u002Fbinary-serialization#circular-references","binary encoder",", on ",[163,2264,1878],{}," and on ",[163,2267,2268],{},"createGetValidationErrorsFn",". In validation, ",[163,2271,2272],{},"validate"," returns ",[163,2275,2276],{},"false",[163,2278,2279],{},"getValidationErrors"," records a ",[163,2282,2283],{},"{expected: 'circular'}"," entry instead of throwing. Decoders need no guard: a serialized payload can't contain a runtime cycle. The whole guard is off by default; arm it only where you process values that might cycle.",[155,2286,2288,2289],{"id":2287},"decoders-return-dataonlyt","Decoders return ",[163,2290,721],{},[160,2292,2293,2294,166,2296,2299,2300,2302,2303,2305],{},"Both ",[163,2295,717],{},[163,2297,2298],{},"createBinaryDecoderFn\u003CT>()"," return ",[163,2301,721],{},", not bare ",[163,2304,588],{},". A value rebuilt from JSON or bytes can only hold serializable data. Anything that can't ride the wire (methods, for one) was never there, so the return type leaves it out and stops you from reaching for it.",[176,2307,2309],{"className":178,"code":2308,"language":180,"meta":181,"style":181},"const decode = createJsonDecoderFn\u003CCart>();\n\n\u002F\u002F The decoder returns DataOnly\u003CCart>, not Cart: the method is gone from the\n\u002F\u002F type because it was never on the wire. TS now stops you from calling it.\nconst cart = decode('{\"items\":[\"TS-7\"],\"total\":42}');\n\ncart.items; \u002F\u002F string[]  ✅\ncart.total; \u002F\u002F number    ✅\n\u002F\u002F cart.checkout();      ❌ TS error: checkout isn't part of DataOnly\u003CCart>\n",[163,2310,2311,2332,2336,2341,2346,2370,2374,2389,2403],{"__ignoreMap":181},[185,2312,2313,2315,2317,2319,2321,2323,2326,2328,2330],{"class":187,"line":188},[185,2314,278],{"class":198},[185,2316,419],{"class":281},[185,2318,395],{"class":206},[185,2320,424],{"class":323},[185,2322,253],{"class":206},[185,2324,2325],{"class":202},"Cart",[185,2327,406],{"class":206},[185,2329,409],{"class":281},[185,2331,226],{"class":206},[185,2333,2334],{"class":187,"line":195},[185,2335,272],{"emptyLinePlaceholder":271},[185,2337,2338],{"class":187,"line":213},[185,2339,2340],{"class":191},"\u002F\u002F The decoder returns DataOnly\u003CCart>, not Cart: the method is gone from the\n",[185,2342,2343],{"class":187,"line":229},[185,2344,2345],{"class":191},"\u002F\u002F type because it was never on the wire. TS now stops you from calling it.\n",[185,2347,2348,2350,2353,2355,2357,2359,2361,2364,2366,2368],{"class":187,"line":242},[185,2349,278],{"class":198},[185,2351,2352],{"class":281}," cart ",[185,2354,395],{"class":206},[185,2356,474],{"class":323},[185,2358,326],{"class":281},[185,2360,307],{"class":206},[185,2362,2363],{"class":303},"{\"items\":[\"TS-7\"],\"total\":42}",[185,2365,307],{"class":206},[185,2367,336],{"class":281},[185,2369,226],{"class":206},[185,2371,2372],{"class":187,"line":262},[185,2373,272],{"emptyLinePlaceholder":271},[185,2375,2376,2379,2381,2384,2386],{"class":187,"line":268},[185,2377,2378],{"class":281},"cart",[185,2380,497],{"class":206},[185,2382,2383],{"class":281},"items",[185,2385,480],{"class":206},[185,2387,2388],{"class":191}," \u002F\u002F string[]  ✅\n",[185,2390,2391,2393,2395,2398,2400],{"class":187,"line":275},[185,2392,2378],{"class":281},[185,2394,497],{"class":206},[185,2396,2397],{"class":281},"total",[185,2399,480],{"class":206},[185,2401,2402],{"class":191}," \u002F\u002F number    ✅\n",[185,2404,2405],{"class":187,"line":293},[185,2406,2407],{"class":191},"\u002F\u002F cart.checkout();      ❌ TS error: checkout isn't part of DataOnly\u003CCart>\n",[160,2409,2410],{},"This isn't a runtime cost. It's the type telling the truth about what came back.",[160,2412,2413,2414,2416,2417,2419],{},"A property whose serialization is guarded by enumerability (anything optional inherited from Error, or one you tag with ",[163,2415,1866],{},") is always optional in the type, so ",[163,2418,721],{}," never claims a value the wire might omit. The type stays honest even for the properties that only sometimes ride the wire.",[155,2421,2423],{"id":2422},"one-contract-serializable-data-only","One contract: serializable data only",[160,2425,2426,2427,2430,2431,2434,2435,497],{},"Validation and both codecs operate on the ",[1086,2428,2429],{},"serializable projection"," of your type, not every last TypeScript member. Functions, methods and symbol keys are silently dropped. They don't survive JSON anyway, so a ",[163,2432,2433],{},"{name: string; onClick: () => void}"," produces a validator that only checks ",[163,2436,1843],{},[160,2438,2439,2440,2443,2444,2447,2448,2451,2452,497],{},"This is on purpose, and the build tells you when it happens with a ",[163,2441,2442],{},"VL010","-family ",[1086,2445,2446],{},"Warning",", not an error. (At a position that would throw at runtime, like a union member or array element, it's escalated to an ",[1086,2449,2450],{},"Error"," and the build fails instead.) The reasoning is in ",[1872,2453,12],{"href":2454},"\u002Fintroduction\u002Fabout-ts-runtypes#a-deliberate-contract-serializable-data",[155,2456,2458],{"id":2457},"work-at-the-value-level","Work at the value level",[160,2460,2461,166,2463,2465],{},[163,2462,165],{},[163,2464,169],{}," give you a string. Sometimes you already own the JSON envelope (a framework that parses one request body and stringifies one response), so you want the transform at the value level, without an extra stringify and parse.",[160,2467,2468,2469,2472,2473,2476,2477,2480,2481,497],{},"The pieces for that are prepareForJson and restoreFromJson: ",[163,2470,2471],{},"prepare"," turns a typed value into a JSON-safe value, ",[163,2474,2475],{},"restore"," turns a JSON-safe value back into the typed shape. The string encoder and decoder are built on exactly these. They have no factory of their own, so you name the one you want in a marker and recover it with ",[163,2478,2479],{},"getRTFunction",", one per strategy. See ",[1872,2482,2484],{"href":2483},"\u002Fguide\u002Fcompiler-markers#recovering-a-function-that-has-no-factory","recovering a function that has no factory",[176,2486,2488],{"className":178,"code":2487,"language":180,"meta":181,"style":181},"\u002F\u002F prepareForJson and restoreFromJson have no factory of their own, so you name\n\u002F\u002F the pair you want in a marker and recover the handles with getRTFunction.\n\u002F\u002F 'pjs' is the clone prepare, 'rj' the matching restore.\nfunction jsonValueCodec\u003CT>(fns?: InjectTypeFnArgs\u003CT, 'pjs', 'rj'>) {\n  return {\n    prepare: getRTFunction\u003C'pjs'>(fns?.[0]),\n    restore: getRTFunction\u003C'rj'>(fns?.[1]),\n  };\n}\n\n\u002F\u002F A concrete call site: the build injects both handles for Message here.\nconst messageCodec = jsonValueCodec\u003CMessage>();\n\nconst message: Message = {id: 42n, sentAt: new Date('2020-01-02T03:04:05.000Z'), body: 'hi'};\n\nconst safe = messageCodec.prepare(message); \u002F\u002F JSON-safe value, no string yet\nconst back = messageCodec.restore(safe); \u002F\u002F typed shape again, bigint and Date included\n",[163,2489,2490,2495,2500,2505,2555,2562,2599,2633,2638,2642,2646,2651,2673,2677,2741,2745,2769],{"__ignoreMap":181},[185,2491,2492],{"class":187,"line":188},[185,2493,2494],{"class":191},"\u002F\u002F prepareForJson and restoreFromJson have no factory of their own, so you name\n",[185,2496,2497],{"class":187,"line":195},[185,2498,2499],{"class":191},"\u002F\u002F the pair you want in a marker and recover the handles with getRTFunction.\n",[185,2501,2502],{"class":187,"line":213},[185,2503,2504],{"class":191},"\u002F\u002F 'pjs' is the clone prepare, 'rj' the matching restore.\n",[185,2506,2507,2510,2513,2515,2517,2520,2523,2526,2529,2531,2533,2535,2537,2540,2542,2544,2546,2549,2551,2553],{"class":187,"line":229},[185,2508,2509],{"class":198},"function",[185,2511,2512],{"class":323}," jsonValueCodec",[185,2514,253],{"class":206},[185,2516,588],{"class":202},[185,2518,2519],{"class":206},">(",[185,2521,2522],{"class":1239},"fns",[185,2524,2525],{"class":206},"?:",[185,2527,2528],{"class":202}," InjectTypeFnArgs",[185,2530,253],{"class":206},[185,2532,588],{"class":202},[185,2534,362],{"class":206},[185,2536,300],{"class":206},[185,2538,2539],{"class":303},"pjs",[185,2541,307],{"class":206},[185,2543,362],{"class":206},[185,2545,300],{"class":206},[185,2547,2548],{"class":303},"rj",[185,2550,307],{"class":206},[185,2552,1386],{"class":206},[185,2554,210],{"class":206},[185,2556,2557,2560],{"class":187,"line":242},[185,2558,2559],{"class":1154},"  return",[185,2561,210],{"class":206},[185,2563,2564,2567,2569,2572,2574,2576,2578,2580,2582,2584,2586,2589,2592,2595,2597],{"class":187,"line":262},[185,2565,2566],{"class":216},"    prepare",[185,2568,220],{"class":206},[185,2570,2571],{"class":323}," getRTFunction",[185,2573,253],{"class":206},[185,2575,307],{"class":206},[185,2577,2539],{"class":303},[185,2579,307],{"class":206},[185,2581,406],{"class":206},[185,2583,326],{"class":216},[185,2585,2522],{"class":281},[185,2587,2588],{"class":206},"?.",[185,2590,2591],{"class":216},"[",[185,2593,2594],{"class":1301},"0",[185,2596,372],{"class":216},[185,2598,310],{"class":206},[185,2600,2601,2604,2606,2608,2610,2612,2614,2616,2618,2620,2622,2624,2626,2629,2631],{"class":187,"line":268},[185,2602,2603],{"class":216},"    restore",[185,2605,220],{"class":206},[185,2607,2571],{"class":323},[185,2609,253],{"class":206},[185,2611,307],{"class":206},[185,2613,2548],{"class":303},[185,2615,307],{"class":206},[185,2617,406],{"class":206},[185,2619,326],{"class":216},[185,2621,2522],{"class":281},[185,2623,2588],{"class":206},[185,2625,2591],{"class":216},[185,2627,2628],{"class":1301},"1",[185,2630,372],{"class":216},[185,2632,310],{"class":206},[185,2634,2635],{"class":187,"line":275},[185,2636,2637],{"class":206},"  };\n",[185,2639,2640],{"class":187,"line":293},[185,2641,1341],{"class":206},[185,2643,2644],{"class":187,"line":313},[185,2645,272],{"emptyLinePlaceholder":271},[185,2647,2648],{"class":187,"line":341},[185,2649,2650],{"class":191},"\u002F\u002F A concrete call site: the build injects both handles for Message here.\n",[185,2652,2653,2655,2658,2660,2662,2664,2667,2669,2671],{"class":187,"line":377},[185,2654,278],{"class":198},[185,2656,2657],{"class":281}," messageCodec ",[185,2659,395],{"class":206},[185,2661,2512],{"class":323},[185,2663,253],{"class":206},[185,2665,2666],{"class":202},"Message",[185,2668,406],{"class":206},[185,2670,409],{"class":281},[185,2672,226],{"class":206},[185,2674,2675],{"class":187,"line":382},[185,2676,272],{"emptyLinePlaceholder":271},[185,2678,2679,2681,2684,2686,2689,2691,2693,2695,2697,2700,2703,2705,2708,2710,2712,2714,2716,2718,2721,2723,2725,2727,2730,2732,2734,2737,2739],{"class":187,"line":387},[185,2680,278],{"class":198},[185,2682,2683],{"class":281}," message",[185,2685,220],{"class":206},[185,2687,2688],{"class":202}," Message",[185,2690,207],{"class":206},[185,2692,684],{"class":206},[185,2694,1568],{"class":216},[185,2696,220],{"class":206},[185,2698,2699],{"class":1301}," 42",[185,2701,2702],{"class":198},"n",[185,2704,362],{"class":206},[185,2706,2707],{"class":216}," sentAt",[185,2709,220],{"class":206},[185,2711,320],{"class":206},[185,2713,237],{"class":323},[185,2715,326],{"class":281},[185,2717,307],{"class":206},[185,2719,2720],{"class":303},"2020-01-02T03:04:05.000Z",[185,2722,307],{"class":206},[185,2724,336],{"class":281},[185,2726,362],{"class":206},[185,2728,2729],{"class":216}," body",[185,2731,220],{"class":206},[185,2733,300],{"class":206},[185,2735,2736],{"class":303},"hi",[185,2738,307],{"class":206},[185,2740,265],{"class":206},[185,2742,2743],{"class":187,"line":414},[185,2744,272],{"emptyLinePlaceholder":271},[185,2746,2747,2749,2752,2754,2757,2759,2761,2764,2766],{"class":187,"line":437},[185,2748,278],{"class":198},[185,2750,2751],{"class":281}," safe ",[185,2753,395],{"class":206},[185,2755,2756],{"class":281}," messageCodec",[185,2758,497],{"class":206},[185,2760,2471],{"class":323},[185,2762,2763],{"class":281},"(message)",[185,2765,480],{"class":206},[185,2767,2768],{"class":191}," \u002F\u002F JSON-safe value, no string yet\n",[185,2770,2771,2773,2775,2777,2779,2781,2783,2786,2788],{"class":187,"line":442},[185,2772,278],{"class":198},[185,2774,469],{"class":281},[185,2776,395],{"class":206},[185,2778,2756],{"class":281},[185,2780,497],{"class":206},[185,2782,2475],{"class":323},[185,2784,2785],{"class":281},"(safe)",[185,2787,480],{"class":206},[185,2789,2790],{"class":191}," \u002F\u002F typed shape again, bigint and Date included\n",[160,2792,2793,2794,2796,2797,2799],{},"Your code owns the ",[163,2795,173],{}," and the ",[163,2798,575],{},", so many values can share one envelope with a single stringify and a single parse.",[160,2801,2802,2803,2806,2807,2810,2811,2813,2814,2273,2816,2818,2819,2821,2822,497],{},"A root ",[163,2804,2805],{},"undefined"," or ",[163,2808,2809],{},"void"," is safe: ",[163,2812,2471],{}," passes the value through and ",[163,2815,2475],{},[163,2817,2805],{},", so neither throws. Wrapping the value in your own envelope (an array or object) is what keeps a bare ",[163,2820,2805],{}," from breaking ",[163,2823,173],{},[2825,2826,2827],"style",{},"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}","Turn a value into JSON and get the same types back, generated from your type.","md",null,{"toc":26},{"title":50,"description":2828},"pjhPyHaTws4Xn4B6vGol6zDzILWWxV0JS5fOWZoOBm4",[2835,2837],{"title":46,"path":47,"stem":48,"description":2836,"children":-1},"Reflect any type into a RunType node, get its stable id, and walk the graph.",{"title":54,"path":55,"stem":56,"description":2838,"children":-1},"The same round trip as JSON, written as compact bytes instead of text.",1787523489065]