@azure-tools/typespec-ts 0.55.0-dev.9 → 0.56.0-dev.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.
- package/CHANGELOG.md +30 -0
- package/dist/src/framework/hooks/sdk-types.d.ts +3 -2
- package/dist/src/framework/hooks/sdk-types.d.ts.map +1 -1
- package/dist/src/framework/hooks/sdk-types.js +3 -2
- package/dist/src/framework/hooks/sdk-types.js.map +1 -1
- package/dist/src/modular/build-classical-client.js +2 -2
- package/dist/src/modular/build-classical-client.js.map +1 -1
- package/dist/src/modular/emit-models.d.ts.map +1 -1
- package/dist/src/modular/emit-models.js +19 -5
- package/dist/src/modular/emit-models.js.map +1 -1
- package/dist/src/modular/emit-samples.js +92 -19
- package/dist/src/modular/emit-samples.js.map +1 -1
- package/dist/src/modular/serialization/serialize-utils.js +2 -2
- package/dist/src/modular/serialization/serialize-utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +12 -10
- package/src/framework/hooks/sdk-types.ts +3 -2
- package/src/modular/build-classical-client.ts +2 -2
- package/src/modular/emit-models.ts +20 -5
- package/src/modular/emit-samples.ts +119 -38
- package/src/modular/serialization/serialize-utils.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.0-dev.0",
|
|
4
4
|
"description": "An experimental TypeSpec emitter for TypeScript",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@azure-tools/typespec-autorest": "^0.69.1 || >=0.70.0-dev <0.70.0",
|
|
27
27
|
"@azure-tools/typespec-azure-core": "^0.69.0 || >=0.70.0-dev <0.70.0",
|
|
28
28
|
"@azure-tools/typespec-azure-resource-manager": "^0.69.1 || >=0.70.0-dev <0.70.0",
|
|
29
|
-
"@azure-tools/typespec-client-generator-core": "^0.69.
|
|
29
|
+
"@azure-tools/typespec-client-generator-core": "^0.69.1 || >=0.70.0-dev <0.70.0",
|
|
30
30
|
"@azure/abort-controller": "^2.1.2",
|
|
31
31
|
"@azure/core-auth": "^1.6.0",
|
|
32
32
|
"@azure/core-lro": "^3.1.0",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@typespec/rest": "^0.83.0 || >=0.84.0-dev <0.84.0",
|
|
41
41
|
"@typespec/versioning": "^0.83.0 || >=0.84.0-dev <0.84.0",
|
|
42
42
|
"@typespec/xml": "^0.83.0 || >=0.84.0-dev <0.84.0",
|
|
43
|
-
"@typespec/ts-http-runtime": "0.3.
|
|
43
|
+
"@typespec/ts-http-runtime": "0.3.6",
|
|
44
44
|
"cross-env": "^10.1.0",
|
|
45
45
|
"mkdirp": "^3.0.1",
|
|
46
46
|
"npm-run-all": "~4.1.5",
|
|
@@ -49,12 +49,11 @@
|
|
|
49
49
|
"vite": "^8.0.8",
|
|
50
50
|
"@vitest/coverage-v8": "^4.1.3",
|
|
51
51
|
"@microsoft/api-extractor": "^7.58.1",
|
|
52
|
-
"tsx": "^4.21.0",
|
|
53
52
|
"yaml": "^2.8.3"
|
|
54
53
|
},
|
|
55
54
|
"peerDependencies": {
|
|
56
55
|
"@azure-tools/typespec-azure-core": "^0.69.0 || >=0.70.0-dev <0.70.0",
|
|
57
|
-
"@azure-tools/typespec-client-generator-core": "^0.69.
|
|
56
|
+
"@azure-tools/typespec-client-generator-core": "^0.69.1 || >=0.70.0-dev <0.70.0",
|
|
58
57
|
"@typespec/compiler": "^1.13.0",
|
|
59
58
|
"@typespec/http": "^1.13.0",
|
|
60
59
|
"@typespec/rest": "^0.83.0 || >=0.84.0-dev <0.84.0",
|
|
@@ -93,23 +92,26 @@
|
|
|
93
92
|
"test:azure": "npm run test-next && npm run copy:typespec && npm run integration-test-ci:azure-modular",
|
|
94
93
|
"lint": "eslint . --ext .ts --max-warnings=0",
|
|
95
94
|
"lint:fix": "eslint . --fix --ext .ts",
|
|
96
|
-
"check:tree": "
|
|
95
|
+
"check:tree": "node ./test/commands/check-clean-tree.ts",
|
|
97
96
|
"test:ts:e2e": "npm run copy:typespec && npm run integration-test-ci:azure-modular",
|
|
98
97
|
"integration-test-ci": "npm-run-all copy:typespec integration-test-ci:azure-modular",
|
|
99
98
|
"integration-test-ci:sequential": "npm-run-all --serial copy:typespec integration-test-ci:azure-modular",
|
|
100
99
|
"integration-test-ci:azure-modular": "npm-run-all --silent -p start-test-server:azure-modular --race generate-and-run:azure-modular",
|
|
101
100
|
"start-test-server": "mkdirp -p coverage && npx tsp-spector serve ./node_modules/@typespec/http-specs/specs --coverageFile ./coverage/spector-coverage-typescript.json",
|
|
102
101
|
"start-test-server:azure-modular": "mkdirp -p coverage && npx tsp-spector serve ./node_modules/@azure-tools/azure-http-specs/specs ./node_modules/@typespec/http-specs/specs --port 3002 --coverageFile ./coverage/spector-coverage-typescript-modular-azure.json",
|
|
103
|
-
"copy:typespec": "
|
|
104
|
-
"generate-and-run:azure-modular": "npm run generate-tsp-only:azure-modular && npm
|
|
102
|
+
"copy:typespec": "node ./test/commands/copy-typespec.ts",
|
|
103
|
+
"generate-and-run:azure-modular": "npm run generate-tsp-only:azure-modular:client && npm-run-all -p integration-test:alone:azure-modular generate-tsp-only:azure-modular:declarations && npm run stop-test-server -- -p 3002",
|
|
105
104
|
"generate-tsp-only": "npm run generate-tsp-only:azure-modular",
|
|
106
|
-
"generate-tsp-only:azure-modular": "
|
|
105
|
+
"generate-tsp-only:azure-modular": "node ./test/commands/gen-spector.js",
|
|
106
|
+
"generate-tsp-only:azure-modular:client": "node ./test/commands/gen-spector.js --phase=client",
|
|
107
|
+
"generate-tsp-only:azure-modular:declarations": "node ./test/commands/gen-spector.js --phase=declarations",
|
|
107
108
|
"regen-test-baselines": "npm run generate-tsp-only",
|
|
108
109
|
"integration-test:alone": "npm run integration-test:alone:azure-modular",
|
|
109
110
|
"integration-test:alone:azure-modular": "vitest run --project integration-azure-modular",
|
|
110
111
|
"stop-test-server": "npx tsp-spector server stop",
|
|
111
112
|
"unit-test": "npm run unit-test:modular",
|
|
112
|
-
"unit-test:modular": "cross-env NODE_OPTIONS=--max-old-space-size=
|
|
113
|
+
"unit-test:modular": "cross-env NODE_OPTIONS=--max-old-space-size=1024 vitest run --project unit-modular",
|
|
114
|
+
"gen:scenario-suites": "node ./test/commands/gen-scenario-suites.ts",
|
|
113
115
|
"regen-docs": "npm run build && tspd doc . --enable-experimental --output-dir ../../website/src/content/docs/docs/emitters/clients/typespec-ts/reference --skip-js"
|
|
114
116
|
}
|
|
115
117
|
}
|
|
@@ -23,10 +23,11 @@ export const flattenPropertyModelMap: Map<SdkModelPropertyType, SdkModelType> =
|
|
|
23
23
|
SdkModelType
|
|
24
24
|
>();
|
|
25
25
|
/**
|
|
26
|
-
* Set of paged result models that
|
|
26
|
+
* Set of paged result models that should keep their public name (no "_" prefix).
|
|
27
|
+
* This includes models used as non-paging method responses or as model properties.
|
|
27
28
|
* Precomputed during visitPackageTypes for O(1) lookups in normalizeModelName.
|
|
28
29
|
*/
|
|
29
|
-
export const
|
|
30
|
+
export const pagedModelsKeptPublic = new Set<SdkType>();
|
|
30
31
|
|
|
31
32
|
export interface SdkTypeContext {
|
|
32
33
|
operations: Map<Type, SdkServiceMethod<SdkHttpOperation>>;
|
|
@@ -290,8 +290,8 @@ function buildClientOperationGroups(
|
|
|
290
290
|
} else {
|
|
291
291
|
// The `rawGroupName` is used to any places where we need normalized name twice so we need to keep the raw as PascalCase.
|
|
292
292
|
const rawGroupName = normalizeName(prefixes[0] ?? "", NameType.Interface);
|
|
293
|
-
const operationName = `_get${
|
|
294
|
-
const propertyType = `${
|
|
293
|
+
const operationName = `_get${rawGroupName}Operations`;
|
|
294
|
+
const propertyType = `${rawGroupName}Operations`;
|
|
295
295
|
// The `groupName` is used to any places where we don't need normalized name again
|
|
296
296
|
const groupName = normalizeName(rawGroupName, NameType.Property);
|
|
297
297
|
const existProperty = clientClass.getProperties().filter((p) => {
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
emitQueue,
|
|
45
45
|
flattenPropertyModelMap,
|
|
46
46
|
getAllOperationsFromClient,
|
|
47
|
-
|
|
47
|
+
pagedModelsKeptPublic,
|
|
48
48
|
} from "../framework/hooks/sdk-types.js";
|
|
49
49
|
import { refkey } from "../framework/refkey.js";
|
|
50
50
|
import { reportDiagnostic } from "../lib.js";
|
|
@@ -841,8 +841,7 @@ export function normalizeModelName(
|
|
|
841
841
|
}
|
|
842
842
|
const namespacePrefix = context.rlcOptions?.enableModelNamespace ? segments.join("") : "";
|
|
843
843
|
const internalModelPrefix =
|
|
844
|
-
(isPagedResultModel(context, type) && !
|
|
845
|
-
type.isGeneratedName
|
|
844
|
+
(isPagedResultModel(context, type) && !pagedModelsKeptPublic.has(type)) || type.isGeneratedName
|
|
846
845
|
? "_"
|
|
847
846
|
: "";
|
|
848
847
|
return `${internalModelPrefix}${normalizeName(namespacePrefix + type.name, nameType, true)}${unionSuffix}`;
|
|
@@ -932,7 +931,7 @@ export function visitPackageTypes(context: SdkContext) {
|
|
|
932
931
|
const { sdkPackage } = context;
|
|
933
932
|
emitQueue.clear();
|
|
934
933
|
flattenPropertyModelMap.clear();
|
|
935
|
-
|
|
934
|
+
pagedModelsKeptPublic.clear();
|
|
936
935
|
// Add all models in the package to the emit queue
|
|
937
936
|
for (const model of sdkPackage.models) {
|
|
938
937
|
visitType(context, model);
|
|
@@ -1015,7 +1014,19 @@ function trackPagedModelInNonPagingMethod(
|
|
|
1015
1014
|
if (method.kind !== "basic" && method.kind !== "lro") return;
|
|
1016
1015
|
const respType = method.response.type;
|
|
1017
1016
|
if (respType && isPagedResultModel(context, respType)) {
|
|
1018
|
-
|
|
1017
|
+
pagedModelsKeptPublic.add(respType);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* If a paged result model is used as a model property type, mark it so that
|
|
1023
|
+
* normalizeModelName keeps it public (no "_" prefix).
|
|
1024
|
+
*/
|
|
1025
|
+
function trackPagedModelUsedAsProperty(context: SdkContext, type: SdkType): void {
|
|
1026
|
+
// Unwrap array types to check the element type
|
|
1027
|
+
const resolved = type.kind === "array" ? type.valueType : type;
|
|
1028
|
+
if (resolved && isPagedResultModel(context, resolved)) {
|
|
1029
|
+
pagedModelsKeptPublic.add(resolved);
|
|
1019
1030
|
}
|
|
1020
1031
|
}
|
|
1021
1032
|
|
|
@@ -1044,6 +1055,10 @@ function visitType(context: SdkContext, type: SdkType | undefined) {
|
|
|
1044
1055
|
if (property.flatten && property.type.kind === "model") {
|
|
1045
1056
|
flattenPropertyModelMap.set(property, type);
|
|
1046
1057
|
}
|
|
1058
|
+
// If a paged result model is used as a model property (not as a paging
|
|
1059
|
+
// operation response), it must stay public (no "_" prefix) because users
|
|
1060
|
+
// interact with it directly through the property.
|
|
1061
|
+
trackPagedModelUsedAsProperty(context, property.type);
|
|
1047
1062
|
}
|
|
1048
1063
|
if (type.discriminatedSubtypes) {
|
|
1049
1064
|
for (const subType of Object.values(type.discriminatedSubtypes)) {
|
|
@@ -316,12 +316,36 @@ function prepareExampleParameters(
|
|
|
316
316
|
|
|
317
317
|
let subscriptionIdValue = `"00000000-0000-0000-0000-000000000000"`;
|
|
318
318
|
let isSubscriptionIdAdded = false;
|
|
319
|
-
|
|
319
|
+
|
|
320
|
+
// Map each HTTP parameter to its method parameter via `methodParameterSegments`
|
|
321
|
+
// and place its example value at that path, yielding one argument per method
|
|
322
|
+
// parameter regardless of flat, nested, or grouped shape. Client- and
|
|
323
|
+
// body-carried roots are emitted by their own sections and skipped here.
|
|
324
|
+
const bodyParam = method.operation.bodyParam;
|
|
325
|
+
let bodyRootName: string | undefined;
|
|
326
|
+
if (
|
|
327
|
+
bodyParam &&
|
|
328
|
+
!isSpreadBodyParameter(bodyParam) &&
|
|
329
|
+
bodyParam.methodParameterSegments.length === 1 &&
|
|
330
|
+
bodyParam.methodParameterSegments[0] !== undefined &&
|
|
331
|
+
bodyParam.methodParameterSegments[0].length >= 1
|
|
332
|
+
) {
|
|
333
|
+
bodyRootName = bodyParam.methodParameterSegments[0][0]!.name;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const methodArguments = new Map<
|
|
337
|
+
string,
|
|
338
|
+
{ name: string; isOptional: boolean; value: ValueTreeNode | string }
|
|
339
|
+
>();
|
|
320
340
|
for (const param of method.operation.parameters) {
|
|
321
|
-
if (param.
|
|
341
|
+
if (param.type.kind === "constant" || param.clientDefaultValue) {
|
|
322
342
|
continue;
|
|
323
343
|
}
|
|
324
|
-
|
|
344
|
+
const path = param.methodParameterSegments[0];
|
|
345
|
+
if (path === undefined || path.length === 0) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const root = path[0]!;
|
|
325
349
|
const exampleValue = parameterMap[param.serializedName];
|
|
326
350
|
|
|
327
351
|
// Handle subscriptionId parameter separately for ARM clients
|
|
@@ -343,28 +367,27 @@ function prepareExampleParameters(
|
|
|
343
367
|
continue;
|
|
344
368
|
}
|
|
345
369
|
|
|
370
|
+
// Roots emitted by the client and body sections.
|
|
371
|
+
if (root.onClient || (bodyRootName !== undefined && root.name === bodyRootName)) {
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
|
|
346
375
|
if (!exampleValue || !exampleValue.value) {
|
|
347
376
|
// report diagnostic if required parameter is missing
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
377
|
+
if (path.length === 1 && !param.optional) {
|
|
378
|
+
reportDiagnostic(dpgContext.program, {
|
|
379
|
+
code: "required-sample-parameter",
|
|
380
|
+
format: {
|
|
381
|
+
exampleName: method.oriName ?? method.name,
|
|
382
|
+
paramName: param.name,
|
|
383
|
+
},
|
|
384
|
+
target: NoTarget,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
356
387
|
continue;
|
|
357
388
|
}
|
|
358
389
|
|
|
359
|
-
|
|
360
|
-
prepareExampleValue(
|
|
361
|
-
dpgContext,
|
|
362
|
-
exampleValue.parameter.name,
|
|
363
|
-
exampleValue.value,
|
|
364
|
-
param.optional,
|
|
365
|
-
param.onClient,
|
|
366
|
-
),
|
|
367
|
-
);
|
|
390
|
+
placeMethodArgument(methodArguments, path, getParameterValue(dpgContext, exampleValue.value));
|
|
368
391
|
}
|
|
369
392
|
|
|
370
393
|
// If client-level subscriptionId is needed on the client for this method, then add it
|
|
@@ -381,7 +404,6 @@ function prepareExampleParameters(
|
|
|
381
404
|
}
|
|
382
405
|
|
|
383
406
|
// required/optional body parameters
|
|
384
|
-
const bodyParam = method.operation.bodyParam;
|
|
385
407
|
const bodySerializeName = bodyParam?.serializedName;
|
|
386
408
|
const bodyExample = parameterMap[bodySerializeName ?? ""];
|
|
387
409
|
if (bodyParam && bodyExample && bodyExample.value) {
|
|
@@ -441,28 +463,87 @@ function prepareExampleParameters(
|
|
|
441
463
|
}
|
|
442
464
|
}
|
|
443
465
|
}
|
|
444
|
-
//
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
result.push(
|
|
453
|
-
prepareExampleValue(
|
|
454
|
-
dpgContext,
|
|
455
|
-
param.parameter.name,
|
|
456
|
-
param.value,
|
|
457
|
-
true,
|
|
458
|
-
param.parameter.onClient,
|
|
459
|
-
),
|
|
460
|
-
);
|
|
466
|
+
// Emit one argument per top-level method parameter. A normal parameter carries
|
|
467
|
+
// a scalar value; a parameter with nested leaves carries an object literal.
|
|
468
|
+
for (const arg of methodArguments.values()) {
|
|
469
|
+
result.push({
|
|
470
|
+
name: normalizeName(arg.name, NameType.Parameter, true),
|
|
471
|
+
value: serializeNestedValue(arg.value),
|
|
472
|
+
isOptional: arg.isOptional,
|
|
473
|
+
onClient: false,
|
|
461
474
|
});
|
|
475
|
+
}
|
|
462
476
|
|
|
463
477
|
return result;
|
|
464
478
|
}
|
|
465
479
|
|
|
480
|
+
/** A nested value tree: leaves are TypeScript value expressions, interior nodes are objects. */
|
|
481
|
+
interface ValueTreeNode {
|
|
482
|
+
[key: string]: ValueTreeNode | string;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Records `leaf` for the method parameter addressed by `path`. `path[0]` is the
|
|
487
|
+
* top-level method parameter (the argument key); a single-segment path stores a
|
|
488
|
+
* scalar, a longer path stores the leaf inside a nested object merged with
|
|
489
|
+
* sibling leaves sharing the same root.
|
|
490
|
+
*/
|
|
491
|
+
function placeMethodArgument(
|
|
492
|
+
methodArguments: Map<
|
|
493
|
+
string,
|
|
494
|
+
{ name: string; isOptional: boolean; value: ValueTreeNode | string }
|
|
495
|
+
>,
|
|
496
|
+
path: readonly { name: string; optional?: boolean }[],
|
|
497
|
+
leaf: string,
|
|
498
|
+
): void {
|
|
499
|
+
const root = path[0]!;
|
|
500
|
+
let arg = methodArguments.get(root.name);
|
|
501
|
+
if (!arg) {
|
|
502
|
+
arg = { name: root.name, isOptional: Boolean(root.optional), value: {} };
|
|
503
|
+
methodArguments.set(root.name, arg);
|
|
504
|
+
}
|
|
505
|
+
if (path.length === 1) {
|
|
506
|
+
arg.value = leaf;
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
if (typeof arg.value !== "object") {
|
|
510
|
+
arg.value = {};
|
|
511
|
+
}
|
|
512
|
+
setNestedValue(arg.value, path.slice(1), leaf);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/** Places `leaf` at `path` (segments after the root), creating intermediate objects as needed. */
|
|
516
|
+
function setNestedValue(
|
|
517
|
+
root: ValueTreeNode,
|
|
518
|
+
path: readonly { name: string }[],
|
|
519
|
+
leaf: string,
|
|
520
|
+
): void {
|
|
521
|
+
let node = root;
|
|
522
|
+
for (let i = 0; i < path.length; i++) {
|
|
523
|
+
const key = normalizeName(path[i]!.name, NameType.Property, true);
|
|
524
|
+
if (i === path.length - 1) {
|
|
525
|
+
node[key] = leaf;
|
|
526
|
+
} else {
|
|
527
|
+
const existing = node[key];
|
|
528
|
+
if (typeof existing !== "object" || existing === null) {
|
|
529
|
+
node[key] = {};
|
|
530
|
+
}
|
|
531
|
+
node = node[key] as ValueTreeNode;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/** Serializes a {@link ValueTreeNode} into a TypeScript object literal string. */
|
|
537
|
+
function serializeNestedValue(node: ValueTreeNode | string): string {
|
|
538
|
+
if (typeof node === "string") {
|
|
539
|
+
return node;
|
|
540
|
+
}
|
|
541
|
+
const entries = Object.entries(node).map(
|
|
542
|
+
([key, value]) => `${key}: ${serializeNestedValue(value)}`,
|
|
543
|
+
);
|
|
544
|
+
return `{ ${entries.join(", ")} }`;
|
|
545
|
+
}
|
|
546
|
+
|
|
466
547
|
function getCredentialExampleValue(
|
|
467
548
|
_dpgContext: SdkContext,
|
|
468
549
|
initialization: SdkClientInitializationType,
|
|
@@ -61,7 +61,7 @@ export function isSupportedSerializeType(type: SdkType): boolean {
|
|
|
61
61
|
* 6. nested model i.e. model with property that is a model with one of the above three conditions.
|
|
62
62
|
* If we consider array type, with all the above 6 types as the element types.
|
|
63
63
|
*/
|
|
64
|
-
const specialVariantMap = new
|
|
64
|
+
const specialVariantMap = new WeakMap<SdkType, boolean>();
|
|
65
65
|
export function isSpecialUnionVariant(
|
|
66
66
|
t: SdkType & { isNonExhaustive?: boolean },
|
|
67
67
|
variantStack: SdkType[] = [],
|
|
@@ -146,7 +146,7 @@ export function isSpecialHandledUnion(t: SdkType & { isNonExhaustive?: boolean }
|
|
|
146
146
|
return isDiscriminatedUnion(t!) || isPolymorphicUnion(t);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
const polymorphicUnionMap = new
|
|
149
|
+
const polymorphicUnionMap = new WeakMap<SdkType, boolean>();
|
|
150
150
|
export function isPolymorphicUnion(t: SdkType): boolean {
|
|
151
151
|
if (polymorphicUnionMap.has(t)) {
|
|
152
152
|
return polymorphicUnionMap.get(t) ?? false;
|