@gi-tcg/gts-transpiler 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ import type {
18
18
  SourceLocation,
19
19
  Statement,
20
20
  VariableDeclaration,
21
+ VariableDeclarator,
21
22
  } from "estree";
22
23
  import {
23
24
  commonGtsVisitor,
@@ -37,10 +38,9 @@ export interface TypingTranspileState extends TranspileState {
37
38
  externalizedBindings: ExternalizedTypedBinding[];
38
39
  idCounter: number;
39
40
  rootVmId: Identifier;
40
- symbolsId: {
41
- Meta: Identifier;
42
- NamedDefinition: Identifier;
43
- };
41
+ utilNsId: Identifier;
42
+ MetaLit: Literal;
43
+ NamedDefinitionLit: Literal;
44
44
  defineLeadingComments: Comment[] | undefined;
45
45
  // type of current VM's definition
46
46
  vmDefTypeIdStack: Identifier[];
@@ -52,11 +52,10 @@ export interface TypingTranspileState extends TranspileState {
52
52
  finalMetaTypeIdStack: Identifier[];
53
53
  // `obj` of `obj.attr(...)`
54
54
  // attrLhsIdStack: Identifier[];
55
- prefaceInserted: boolean;
56
55
  /** Pending statements to be inserted to the top-level */
57
- pendingStatements: Statement[];
56
+ typingPendingStatements: Statement[];
58
57
  replacementTag: Identifier;
59
- additionalMappings: Map<string, string>;
58
+ extraMappings: Map<string, string>;
60
59
  }
61
60
 
62
61
  const EMPTY: EmptyStatement = { type: "EmptyStatement" };
@@ -73,68 +72,7 @@ const ANY_INIT = {
73
72
  typeAnnotation: ANY,
74
73
  } as {} as Expression;
75
74
 
76
- const emitPreface = (state: TypingTranspileState) => {
77
- if (state.prefaceInserted) {
78
- return;
79
- }
80
- const symbolsLhs = {
81
- type: "TSQualifiedName",
82
- left: { type: "Identifier", name: state.rootVmId.name },
83
- right: { type: "Identifier", name: "_symbols" },
84
- };
85
- for (const symbolName of [
86
- "Meta",
87
- "Action",
88
- "NamedDefinition",
89
- "Prelude",
90
- ] as const) {
91
- const init = {
92
- type: "TSTypeQuery",
93
- exprName: {
94
- type: "TSQualifiedName",
95
- left: symbolsLhs,
96
- right: { type: "Identifier", name: symbolName },
97
- },
98
- };
99
- const symbolId =
100
- symbolName === "Action"
101
- ? state.ActionId
102
- : symbolName === "Prelude"
103
- ? state.preludeSymbolId
104
- : state.symbolsId[symbolName];
105
- state.pendingStatements.push(
106
- {
107
- type: "TSTypeAliasDeclaration",
108
- id: symbolId,
109
- typeAnnotation: init,
110
- } as {} as VariableDeclaration,
111
- {
112
- type: "VariableDeclaration",
113
- kind: "const",
114
- declarations: [
115
- {
116
- type: "VariableDeclarator",
117
- id: {
118
- ...symbolId,
119
- typeAnnotation: {
120
- type: "TSTypeAnnotation",
121
- typeAnnotation: {
122
- type: "TSTypeReference",
123
- typeName: symbolId,
124
- },
125
- },
126
- } as Identifier,
127
- init: ANY_INIT,
128
- },
129
- ],
130
- } as VariableDeclaration
131
- );
132
- }
133
- state.prefaceInserted = true;
134
- };
135
-
136
75
  const enterVMFromRoot = (state: TypingTranspileState) => {
137
- emitPreface(state);
138
76
  let defTypeId: Identifier = {
139
77
  type: "Identifier",
140
78
  name: `__gts_rootVmDefType_${state.idCounter++}`,
@@ -147,13 +85,13 @@ const enterVMFromRoot = (state: TypingTranspileState) => {
147
85
  type: "Identifier",
148
86
  name: `__gts_rootVmFinalMetaType_${state.idCounter++}`,
149
87
  };
150
- state.pendingStatements.push(
88
+ state.typingPendingStatements.push(
151
89
  createReplacementHolder(state, {
152
90
  type: "enterVMFromRoot",
153
91
  vm: state.rootVmId.name,
154
92
  defType: defTypeId.name,
155
93
  metaType: metaTypeId.name,
156
- })
94
+ }),
157
95
  );
158
96
  state.vmDefTypeIdStack.push(defTypeId);
159
97
  state.metaTypeIdStack.push(metaTypeId);
@@ -162,7 +100,7 @@ const enterVMFromRoot = (state: TypingTranspileState) => {
162
100
  };
163
101
  const enterVMFromAttr = (
164
102
  state: TypingTranspileState,
165
- returningId: Identifier
103
+ returningId: Identifier,
166
104
  ) => {
167
105
  const defTypeId: Identifier = {
168
106
  type: "Identifier",
@@ -176,13 +114,13 @@ const enterVMFromAttr = (
176
114
  type: "Identifier",
177
115
  name: `__gts_nestedVmFinalMetaType_${state.idCounter++}`,
178
116
  };
179
- state.pendingStatements.push(
117
+ state.typingPendingStatements.push(
180
118
  createReplacementHolder(state, {
181
119
  type: "enterVMFromAttr",
182
120
  returnType: returningId.name,
183
121
  defType: defTypeId.name,
184
122
  metaType: metaTypeId.name,
185
- })
123
+ }),
186
124
  );
187
125
  state.vmDefTypeIdStack.push(defTypeId);
188
126
  state.metaTypeIdStack.push(metaTypeId);
@@ -195,7 +133,7 @@ const exitVM = (state: TypingTranspileState, errorLoc?: string) => {
195
133
  const currentMetaId = state.metaTypeIdStack.pop()!;
196
134
  const finalMetaId = state.finalMetaTypeIdStack.pop()!;
197
135
  const collectedAttrNames = state.attrsOfCurrentVm.pop()!;
198
- state.pendingStatements.push(
136
+ state.typingPendingStatements.push(
199
137
  createReplacementHolder(state, {
200
138
  type: "exitVM",
201
139
  metaType: currentMetaId.name,
@@ -203,13 +141,13 @@ const exitVM = (state: TypingTranspileState, errorLoc?: string) => {
203
141
  finalMetaType: finalMetaId.name,
204
142
  collectedAttrs: collectedAttrNames,
205
143
  errorLoc,
206
- })
144
+ }),
207
145
  );
208
146
  };
209
147
 
210
148
  const enterAttr = (
211
149
  state: TypingTranspileState,
212
- attrName: string
150
+ attrName: string,
213
151
  ): { lhsId: Identifier } => {
214
152
  const defTypeId = state.vmDefTypeIdStack.at(-1);
215
153
  const metaTypeId = state.metaTypeIdStack.at(-1);
@@ -222,13 +160,14 @@ const enterAttr = (
222
160
  type: "Identifier",
223
161
  name: `__gts_attr_obj_${state.idCounter++}`,
224
162
  };
225
- state.pendingStatements.push(
163
+ state.typingPendingStatements.push(
226
164
  createReplacementHolder(state, {
227
165
  type: "enterAttr",
228
166
  defType: defTypeId.name,
229
167
  metaType: metaTypeId.name,
230
168
  lhs: lhsId.name,
231
- })
169
+ attrName,
170
+ }),
232
171
  );
233
172
  return { lhsId: lhsId };
234
173
  };
@@ -238,21 +177,21 @@ const genBindingTyping = (
238
177
  info: {
239
178
  attrName: string;
240
179
  typingId: Identifier;
241
- }
180
+ },
242
181
  ) => {
243
182
  const finalMetaId = state.finalMetaTypeIdStack.at(-1);
244
183
  const defTypeId = state.vmDefTypeIdStack.at(-1);
245
184
  if (!finalMetaId || !defTypeId) {
246
185
  return;
247
186
  }
248
- state.pendingStatements.push(
187
+ state.typingPendingStatements.push(
249
188
  createReplacementHolder(state, {
250
189
  type: "createBindingTyping",
251
190
  finalMetaType: finalMetaId.name,
252
191
  defType: defTypeId.name,
253
192
  attrName: info.attrName,
254
193
  typingId: info.typingId.name,
255
- })
194
+ }),
256
195
  );
257
196
  };
258
197
 
@@ -266,14 +205,14 @@ const exitAttr = (state: TypingTranspileState, returningId: Identifier) => {
266
205
  name: `__gts_newMeta__${state.idCounter++}`,
267
206
  };
268
207
  const [oldMetaTypeId] = state.metaTypeIdStack.splice(-1, 1, newMetaTypeId);
269
- state.pendingStatements.push(
208
+ state.typingPendingStatements.push(
270
209
  createReplacementHolder(state, {
271
210
  type: "exitAttr",
272
211
  defType: currentDefId.name,
273
212
  oldMetaType: oldMetaTypeId.name,
274
213
  newMetaType: newMetaTypeId.name,
275
214
  returnType: returningId.name,
276
- })
215
+ }),
277
216
  );
278
217
  };
279
218
 
@@ -286,133 +225,82 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
286
225
  ) {
287
226
  state.defineLeadingComments = stmt.leadingComments;
288
227
  visit(stmt);
289
- body.push(...state.pendingStatements);
290
- state.pendingStatements = [];
228
+ body.push(...state.typingPendingStatements);
229
+ state.typingPendingStatements = [];
291
230
  } else {
292
231
  body.push(visit(stmt) as Statement);
293
232
  }
294
233
  }
295
- if (state.externalizedBindings.length > 0) {
296
- body.unshift(
297
- {
298
- type: "ImportDeclaration",
299
- specifiers: [
300
- {
301
- type: "ImportDefaultSpecifier",
302
- local: state.binderFnId,
234
+ for (const extBinding of state.externalizedBindings) {
235
+ const varDecl: VariableDeclaration = {
236
+ type: "VariableDeclaration",
237
+ kind: "const",
238
+ declarations: [
239
+ {
240
+ type: "VariableDeclarator",
241
+ id: extBinding.bindingName,
242
+ init: ANY_INIT,
243
+ typeAnnotation: {
244
+ type: "TSTypeAnnotation",
245
+ typeAnnotation: {
246
+ type: "TSTypeReference",
247
+ typeName: extBinding.typingId,
248
+ },
303
249
  },
304
- ],
305
- source: {
306
- type: "Literal",
307
- value: `${state.providerImportSource}/binder`,
308
- },
250
+ } as VariableDeclarator,
251
+ ],
252
+ };
253
+ if (extBinding.export) {
254
+ body.unshift({
255
+ type: "ExportNamedDeclaration",
256
+ declaration: varDecl,
257
+ specifiers: [],
258
+ source: null,
309
259
  attributes: [],
310
- },
311
- ...state.externalizedBindings.flatMap(
312
- (binding): (Declaration | ExportNamedDeclaration)[] => {
313
- const internalDecl: Declaration = {
314
- type: "VariableDeclaration",
315
- kind: "const",
316
- declarations: [
317
- {
318
- type: "VariableDeclarator",
319
- id: binding.internalId,
320
- init: binding.value,
321
- },
322
- ],
323
- };
324
- const externalDecl: Declaration = {
325
- type: "VariableDeclaration",
326
- kind: "const",
327
- declarations: [
328
- {
329
- type: "VariableDeclarator",
330
- id: binding.bindingName,
331
- init: {
332
- type: "CallExpression",
333
- optional: false,
334
- callee: state.binderFnId,
335
- arguments: [
336
- binding.internalId,
337
- {
338
- type: "ObjectExpression",
339
- properties: [
340
- {
341
- type: "Property",
342
- key: { type: "Identifier", name: "path" },
343
- computed: false,
344
- kind: "init",
345
- method: false,
346
- shorthand: false,
347
- value: {
348
- type: "ArrayExpression",
349
- elements: binding.path.map((segment) => ({
350
- type: "Literal",
351
- value: segment,
352
- })),
353
- },
354
- },
355
- ],
356
- },
357
- ],
358
- },
359
- },
360
- ],
361
- };
362
- return binding.export
363
- ? [
364
- internalDecl,
365
- {
366
- type: "ExportNamedDeclaration",
367
- declaration: externalDecl,
368
- specifiers: [],
369
- attributes: [],
370
- leadingComments: binding.leadingComments,
371
- },
372
- ]
373
- : [
374
- internalDecl,
375
- {
376
- ...externalDecl,
377
- leadingComments: binding.leadingComments,
378
- },
379
- ];
380
- }
381
- )
382
- );
260
+ leadingComments: extBinding.leadingComments,
261
+ } as ExportNamedDeclaration);
262
+ } else {
263
+ varDecl.leadingComments = extBinding.leadingComments;
264
+ body.unshift(varDecl);
265
+ }
383
266
  }
384
- if (state.prefaceInserted) {
267
+ if (state.hasQueryExpressions) {
385
268
  body.unshift({
386
269
  type: "ImportDeclaration",
270
+ diagnosticsOnTop: true,
387
271
  specifiers: [
388
272
  {
389
273
  type: "ImportDefaultSpecifier",
390
- local: state.rootVmId,
274
+ local: state.queryFnId,
391
275
  },
392
276
  ],
393
277
  source: {
394
278
  type: "Literal",
395
- value: `${state.providerImportSource}/rootVM`,
279
+ value: `${state.providerImportSource}/query`,
396
280
  },
397
281
  attributes: [],
398
282
  });
399
283
  }
400
- if (state.hasQueryExpressions) {
401
- body.unshift({
284
+ body.unshift(
285
+ {
402
286
  type: "ImportDeclaration",
287
+ diagnosticsOnTop: true,
403
288
  specifiers: [
404
289
  {
405
290
  type: "ImportDefaultSpecifier",
406
- local: state.queryFnId,
291
+ local: state.rootVmId,
407
292
  },
408
293
  ],
409
294
  source: {
410
295
  type: "Literal",
411
- value: `${state.providerImportSource}/query`,
296
+ value: `${state.providerImportSource}/vm`,
412
297
  },
413
298
  attributes: [],
414
- });
415
- }
299
+ },
300
+ createReplacementHolder(state, {
301
+ type: "preface",
302
+ }),
303
+ );
416
304
  return {
417
305
  ...node,
418
306
  body,
@@ -427,18 +315,24 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
427
315
  GTSNamedAttributeDefinition(node, { visit, state }) {
428
316
  const { name, body, bindingName } = node;
429
317
  const attrName = JSON.stringify(
430
- name.type === "Literal" ? String(name.value) : name.name
318
+ name.type === "Literal" ? String(name.value) : name.name,
431
319
  );
320
+ const attributeNameToken = state.leafTokens.find((t) => t.loc === name.loc);
321
+ if (attributeNameToken) {
322
+ attributeNameToken.sourceLengthOffset = 1;
323
+ }
432
324
  const { lhsId } = enterAttr(state, attrName);
325
+ state.extraMappings.set(
326
+ `${name.loc?.start.line}:${name.loc?.start.column}`,
327
+ `${lhsId.name}${name.type === "Literal" ? `[` : `.`}`,
328
+ );
433
329
  const positionals = body.positionalAttributes.attributes.map(
434
330
  (attr): Expression => {
435
331
  if (attr.type === "Identifier" && /^[a-z_]/.test(attr.name)) {
436
332
  const token = state.leafTokens.find((t) => t.loc === attr.loc);
437
333
  if (token) {
438
- token.locationAdjustment = {
439
- startOffset: 1,
440
- generatedLength: attr.name.length + 2, // quotation mark
441
- };
334
+ token.generatedStartOffset = 1;
335
+ token.generatedLength = attr.name.length + 2; // quotation mark
442
336
  }
443
337
  return {
444
338
  type: "Literal",
@@ -448,13 +342,13 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
448
342
  } else {
449
343
  return visit(attr) as Expression;
450
344
  }
451
- }
345
+ },
452
346
  );
453
347
  const returnValue: Identifier = {
454
348
  type: "Identifier",
455
349
  name: `__gts_attrRet_${state.idCounter++}`,
456
350
  };
457
- state.pendingStatements.push({
351
+ state.typingPendingStatements.push({
458
352
  type: "VariableDeclaration",
459
353
  kind: "const",
460
354
  declarations: [
@@ -481,15 +375,11 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
481
375
  visit(body.namedAttributes);
482
376
  exitVM(
483
377
  state,
484
- `${body.namedAttributes.loc?.start.line}:${body.namedAttributes.loc?.start.column}`
378
+ `${body.namedAttributes.loc?.start.line}:${body.namedAttributes.loc?.start.column}`,
485
379
  );
486
380
  }
487
381
  if (bindingName) {
488
382
  const export_ = node.bindingAccessModifier !== "private";
489
- const internalId: Identifier = {
490
- type: "Identifier",
491
- name: `__gts_internal_binding_${state.externalizedBindings.length}`,
492
- };
493
383
  const typingId: Identifier = {
494
384
  type: "Identifier",
495
385
  name: `gts_binding_type_${state.externalizedBindings.length}`,
@@ -510,15 +400,6 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
510
400
  },
511
401
  } as Identifier,
512
402
  export: export_,
513
- internalId,
514
- value: { type: "Literal", value: null }, // TODO
515
- path: [...state.attributeNames, node.name].map((n) => {
516
- if (n.type === "Literal") {
517
- return String(n.value);
518
- } else {
519
- return n.name;
520
- }
521
- }),
522
403
  typingId,
523
404
  leadingComments: state.defineLeadingComments,
524
405
  });
@@ -531,7 +412,14 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
531
412
  visit(attr);
532
413
  }
533
414
  if (node.directAction) {
534
- const { lhsId } = enterAttr(state, state.ActionId.name);
415
+ const attrName = JSON.stringify(state.ActionLit.value);
416
+ const { lhsId } = enterAttr(state, attrName);
417
+ const actionNotExistsReplacementStr = `${lhsId.name}[${attrName}]`;
418
+ const actionNotExistsErrorLoc = `${node.directAction.loc?.start.line}:${node.directAction.loc?.start.column}`;
419
+ state.extraMappings.set(
420
+ actionNotExistsErrorLoc,
421
+ actionNotExistsReplacementStr,
422
+ );
535
423
  const fn: ArrowFunctionExpression = {
536
424
  type: "ArrowFunctionExpression",
537
425
  params: state.shortcutFunctionParameters,
@@ -545,7 +433,7 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
545
433
  type: "Identifier",
546
434
  name: `__gts_attrRet_${state.idCounter++}`,
547
435
  };
548
- state.pendingStatements.push({
436
+ state.typingPendingStatements.push({
549
437
  type: "VariableDeclaration",
550
438
  kind: "const",
551
439
  declarations: [
@@ -558,7 +446,7 @@ export const gtsToTypingsWalker: Visitors<Node, TypingTranspileState> = {
558
446
  callee: {
559
447
  type: "MemberExpression",
560
448
  object: lhsId,
561
- property: state.ActionId,
449
+ property: state.ActionLit,
562
450
  computed: true,
563
451
  optional: false,
564
452
  },
package/src/types.ts CHANGED
@@ -25,6 +25,18 @@ declare module "estree" {
25
25
  GTSQueryExpression: GTSQueryExpression;
26
26
  }
27
27
 
28
+ interface ImportDeclaration {
29
+ /** Emit inner diagnostics to the top-of-file */
30
+ diagnosticsOnTop?: boolean;
31
+ }
32
+
33
+ interface SimpleCallExpression {
34
+ lParenLoc?: SourceLocation;
35
+ }
36
+ interface NewExpression {
37
+ lParenLoc?: SourceLocation;
38
+ }
39
+
28
40
  interface GTSDefineStatement extends BaseStatement {
29
41
  type: "GTSDefineStatement";
30
42
  body: GTSNamedAttributeDefinition;
@@ -32,10 +44,10 @@ declare module "estree" {
32
44
 
33
45
  interface GTSNamedAttributeDefinition extends BaseNode {
34
46
  type: "GTSNamedAttributeDefinition";
35
- name: AST.Identifier | AST.Literal;
47
+ name: Identifier | Literal;
36
48
  body: GTSAttributeBody;
37
49
  bindingAccessModifier?: "public" | "protected" | "private";
38
- bindingName?: AST.Identifier;
50
+ bindingName?: Identifier;
39
51
  }
40
52
 
41
53
  interface GTSAttributeBody extends BaseNode {
@@ -46,7 +58,7 @@ declare module "estree" {
46
58
 
47
59
  interface GTSPositionalAttributeList extends BaseNode {
48
60
  type: "GTSPositionalAttributeList";
49
- attributes: AST.Expression[];
61
+ attributes: Expression[];
50
62
  }
51
63
 
52
64
  interface GTSNamedAttributeBlock extends BaseNode {
@@ -67,7 +79,7 @@ declare module "estree" {
67
79
 
68
80
  interface GTSShortcutFunctionExpression extends BaseExpression {
69
81
  type: "GTSShortcutFunctionExpression";
70
- body: AST.BlockStatement | AST.Expression;
82
+ body: BlockStatement | Expression;
71
83
  expression: boolean;
72
84
  }
73
85
 
@@ -1,112 +0,0 @@
1
- # transpiler 构思
2
-
3
- 对于每个 named attribute,生成一个函数返回 attribute information;define 语句返回 `createDefine`
4
-
5
- ```ts
6
- define foo bar, baz, {
7
- a 42;
8
- }
9
- ```
10
-
11
- ```js
12
- import { createDefine } from "@gi-tcg/gts-runtime";
13
- import rootVM from "#provider/vm";
14
-
15
- createDefine(rootVM, {
16
- attributes: [
17
- () => ({
18
- name: "foo",
19
- positionals: ["bar", "baz"],
20
- named: {
21
- attributes: [
22
- () => ({
23
- name: "a",
24
- positionals: [42],
25
- })
26
- ]
27
- }
28
- })
29
- ]
30
- });
31
- ```
32
-
33
- ## bindings
34
-
35
- 对于 bindings,将所有 binding 本身的 attribute definition 提出来,然后用 binder 返回具体值:
36
-
37
- ```
38
- define foo bar, baz, {
39
- id 1101 as Ganyu;
40
- a 42;
41
- }
42
- ```
43
-
44
- ```js
45
- import { createDefine } from "@gi-tcg/gts-runtime";
46
- import rootVM from "#provider/vm";
47
- import binder from "#provider/binder";
48
-
49
- // ALWAYS on top of the module
50
- const __id_attribute = () => ({
51
- name: "id",
52
- positionals: [1101],
53
- })
54
- export const Ganyu = binder(__id_attribute, {
55
- path: ["foo", "id"],
56
- });
57
-
58
- // -----
59
-
60
- createDefine(rootVM, {
61
- attributes: [
62
- () => ({
63
- name: "foo",
64
- positionals: ["bar", "baz"],
65
- named: {
66
- attributes: [
67
- __id_attribute,
68
- () => ({
69
- name: "a",
70
- positionals: [42],
71
- })
72
- ]
73
- }
74
- })
75
- ]
76
- });
77
- ```
78
-
79
- ## TS VirtualCode
80
-
81
- 不产出真实运行时代码,只产出类型推导代码
82
-
83
- ```
84
- define foo bar, baz, {
85
- id 1101 as Ganyu;
86
- a 42;
87
- }
88
- ```
89
-
90
- ```ts
91
- import rootVM from "#provider/vm";
92
- import binder from "#provider/binder";
93
-
94
- export const Ganyu: Binding0 = (void 0)!;
95
-
96
- type VMDef = (typeof rootVM)[NamedDefinition];
97
- type Meta0 = VMDef[Meta];
98
-
99
- let obj0!: { [Meta]: Meta0 } & Omit<VMDef, Meta>;
100
- let return0 = obj0.id(123); // <- cursor after `.` for suggestion of attribute name; after `(` for positional args
101
- type Return0 = typeof return0;
102
- // Override parent meta: Attatch `rewriteMeta` to obj's [Meta]
103
- type Meta1 = Return0 extends { rewriteMeta: infer NewMeta extends {} } ? NewMeta : Meta0;
104
- let obj1!: { [Meta]: Meta1 } & Omit<VMDef, Meta>;
105
- // Infer binding type: Attach `as` to a [Meta]-contained object
106
- type AsType0 = typeof obj0.id extends { as: infer As } ? As : unknown;
107
- let inferBindingObj0 = { [Meta]: obj1[Meta], as: 0 as any as AsType1 };
108
- let binding0 = inferBindingObj0.as();
109
- type Binding0 = typeof binding0;
110
-
111
- let return1 = obj1.a(42); // same as above
112
- ```