diff --git a/.chronus/changes/fionabronwen-type-utils-2026-0-12-16-12-5.md b/.chronus/changes/fionabronwen-type-utils-2026-0-12-16-12-5.md new file mode 100644 index 00000000000..5794d04d58f --- /dev/null +++ b/.chronus/changes/fionabronwen-type-utils-2026-0-12-16-12-5.md @@ -0,0 +1,12 @@ +--- +changeKind: deprecation +packages: + - "@typespec/compiler" + - "@typespec/http" + - "@typespec/openapi3" + - "@typespec/tspd" + - "@typespec/http-server-js" + - "@typespec/http-server-csharp" +--- + +Deprecate `program` parameter in `isArrayModelType` and `isRecordModelType` functions. Use the new single-argument overload instead: `isArrayModelType(type)` and `isRecordModelType(type)`. diff --git a/packages/compiler/src/core/checker.ts b/packages/compiler/src/core/checker.ts index 27fc653172f..75259b386bf 100644 --- a/packages/compiler/src/core/checker.ts +++ b/packages/compiler/src/core/checker.ts @@ -4730,7 +4730,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker ); return [[], undefined]; } - if (isArrayModelType(program, targetType)) { + if (isArrayModelType(targetType)) { reportCheckerDiagnostic( createDiagnostic({ code: "spread-model", target: targetNode }), mapper, @@ -5096,17 +5096,14 @@ export function createChecker(program: Program, resolver: NameResolver): Checker let valueType: Type | undefined; let type: Type | undefined; if (constraint.valueType) { - if ( - constraint.valueType.kind === "Model" && - isArrayModelType(program, constraint.valueType) - ) { + if (constraint.valueType.kind === "Model" && isArrayModelType(constraint.valueType)) { valueType = constraint.valueType.indexer.value; } else { return undefined; } } if (constraint.type) { - if (constraint.type.kind === "Model" && isArrayModelType(program, constraint.type)) { + if (constraint.type.kind === "Model" && isArrayModelType(constraint.type)) { type = constraint.type.indexer.value; } else { return undefined; diff --git a/packages/compiler/src/core/type-relation-checker.ts b/packages/compiler/src/core/type-relation-checker.ts index dc0e02948ae..5444e682d4b 100644 --- a/packages/compiler/src/core/type-relation-checker.ts +++ b/packages/compiler/src/core/type-relation-checker.ts @@ -321,12 +321,8 @@ export function createTypeRelationChecker(program: Program, checker: Checker): T }), ], ]; - } else if ( - target.kind === "Model" && - isArrayModelType(program, target) && - source.kind === "Model" - ) { - if (isArrayModelType(program, source)) { + } else if (target.kind === "Model" && isArrayModelType(target) && source.kind === "Model") { + if (isArrayModelType(source)) { return hasIndexAndIsAssignableTo( source, target as Model & { indexer: ModelIndexer }, @@ -339,11 +335,7 @@ export function createTypeRelationChecker(program: Program, checker: Checker): T } } else if (target.kind === "Model" && source.kind === "Model") { return areModelsRelated(source, target, diagnosticTarget, relationCache); - } else if ( - target.kind === "Model" && - isArrayModelType(program, target) && - source.kind === "Tuple" - ) { + } else if (target.kind === "Model" && isArrayModelType(target) && source.kind === "Tuple") { return isTupleAssignableToArray(source, target, diagnosticTarget, relationCache); } else if (target.kind === "Tuple" && source.kind === "Tuple") { return isTupleAssignableToTuple(source, target, diagnosticTarget, relationCache); diff --git a/packages/compiler/src/core/type-utils.ts b/packages/compiler/src/core/type-utils.ts index db513bac9d9..8e5f471da0c 100644 --- a/packages/compiler/src/core/type-utils.ts +++ b/packages/compiler/src/core/type-utils.ts @@ -11,6 +11,7 @@ import { Node, NullType, Operation, + RecordModelType, Sym, SymbolFlags, SyntaxKind, @@ -51,17 +52,36 @@ export function isValue(entity: Entity): entity is Value { } /** + * Check if a model is an array type. + * @param program Program (unused) + * @param type Model type + * @deprecated Use `isArrayModelType(type)` instead. The `program` parameter is unused. + */ +export function isArrayModelType(program: Program, type: Model): type is ArrayModelType; +/** + * Check if a model is an array type. * @param type Model type */ -export function isArrayModelType(program: Program, type: Model): type is ArrayModelType { +export function isArrayModelType(type: Model): type is ArrayModelType; +export function isArrayModelType(programOrType: Program | Model, maybeType?: Model): boolean { + const type = maybeType ?? (programOrType as Model); return Boolean(type.indexer && type.indexer.key.name === "integer"); } /** - * Check if a model is an array type. + * Check if a model is a record type. + * @param program Program (unused) + * @param type Model type + * @deprecated Use `isRecordModelType(type)` instead. The `program` parameter is unused. + */ +export function isRecordModelType(program: Program, type: Model): type is RecordModelType; +/** + * Check if a model is a record type. * @param type Model type */ -export function isRecordModelType(program: Program, type: Model): type is ArrayModelType { +export function isRecordModelType(type: Model): type is RecordModelType; +export function isRecordModelType(programOrType: Program | Model, maybeType?: Model): boolean { + const type = maybeType ?? (programOrType as Model); return Boolean(type.indexer && type.indexer.key.name === "string"); } diff --git a/packages/compiler/src/index.ts b/packages/compiler/src/index.ts index bb4bd74d20e..301336ab3a3 100644 --- a/packages/compiler/src/index.ts +++ b/packages/compiler/src/index.ts @@ -284,6 +284,7 @@ export { type NavigationOptions, } from "./core/semantic-walker.js"; export { createSourceFile, getSourceFileKindFromExt } from "./core/source-file.js"; +/* eslint-disable @typescript-eslint/no-deprecated -- exporting deprecated overloads for backward compatibility */ export { isArrayModelType, isDeclaredInNamespace, @@ -301,6 +302,7 @@ export { isValue, isVoidType, } from "./core/type-utils.js"; +/* eslint-enable @typescript-eslint/no-deprecated */ export { ListenerFlow, NoTarget } from "./core/types.js"; export type { ArrayModelType, diff --git a/packages/compiler/src/lib/decorators.ts b/packages/compiler/src/lib/decorators.ts index cc36071911e..4ab03e7a673 100644 --- a/packages/compiler/src/lib/decorators.ts +++ b/packages/compiler/src/lib/decorators.ts @@ -390,10 +390,7 @@ function validateTargetingAnArray( decoratorName: string, ) { const targetType = getTypeForArrayValidation(target); - const valid = isTypeIn( - targetType, - (x) => x.kind === "Model" && isArrayModelType(context.program, x), - ); + const valid = isTypeIn(targetType, (x) => x.kind === "Model" && isArrayModelType(x)); if (!valid) { reportDiagnostic(context.program, { code: "decorator-wrong-target", diff --git a/packages/compiler/src/lib/examples.ts b/packages/compiler/src/lib/examples.ts index 87e77dedd9d..f114f31b7c4 100644 --- a/packages/compiler/src/lib/examples.ts +++ b/packages/compiler/src/lib/examples.ts @@ -40,7 +40,7 @@ export function serializeValueAsJson( serializeValueAsJson( program, v, - type.kind === "Model" && isArrayModelType(program, type) + type.kind === "Model" && isArrayModelType(type) ? type.indexer.value : program.checker.anyType, ), diff --git a/packages/compiler/src/lib/paging.ts b/packages/compiler/src/lib/paging.ts index f0ed07f32c5..54147351f07 100644 --- a/packages/compiler/src/lib/paging.ts +++ b/packages/compiler/src/lib/paging.ts @@ -87,7 +87,7 @@ export const [ /** {@inheritdoc PageItemsDecorator} */ pageItemsDecorator, ] = createMarkerDecorator("pageItems", (context, target) => { - if (target.type.kind !== "Model" || !isArrayModelType(context.program, target.type)) { + if (target.type.kind !== "Model" || !isArrayModelType(target.type)) { reportDiagnostic(context.program, { code: "decorator-wrong-target", messageId: "withExpected", diff --git a/packages/compiler/src/typekit/kits/array.ts b/packages/compiler/src/typekit/kits/array.ts index 67059b7a8e5..7b1c4abaa74 100644 --- a/packages/compiler/src/typekit/kits/array.ts +++ b/packages/compiler/src/typekit/kits/array.ts @@ -35,7 +35,7 @@ defineKit({ return ( type.entityKind === "Type" && type.kind === "Model" && - isArrayModelType(this.program, type) && + isArrayModelType(type) && type.properties.size === 0 ); }, diff --git a/packages/compiler/src/typekit/kits/record.ts b/packages/compiler/src/typekit/kits/record.ts index bf83a4ef0d7..4f140d228b6 100644 --- a/packages/compiler/src/typekit/kits/record.ts +++ b/packages/compiler/src/typekit/kits/record.ts @@ -39,7 +39,7 @@ defineKit({ return ( type.entityKind === "Type" && type.kind === "Model" && - isRecordModelType(this.program, type) && + isRecordModelType(type) && type.properties.size === 0 ); }, diff --git a/packages/compiler/test/checker/model.test.ts b/packages/compiler/test/checker/model.test.ts index d80ba03b62a..46f9d7a63a4 100644 --- a/packages/compiler/test/checker/model.test.ts +++ b/packages/compiler/test/checker/model.test.ts @@ -847,7 +847,7 @@ describe("compiler: models", () => { `, ); const { A } = (await testHost.compile("main.tsp")) as { A: Model }; - ok(isArrayModelType(testHost.program, A)); + ok(isArrayModelType(A)); }); it("model is accept array expression of complex type", async () => { @@ -859,7 +859,7 @@ describe("compiler: models", () => { `, ); const { A } = (await testHost.compile("main.tsp")) as { A: Model }; - ok(isArrayModelType(testHost.program, A)); + ok(isArrayModelType(A)); strictEqual(A.indexer.value.kind, "Union"); }); @@ -1124,7 +1124,7 @@ describe("compiler: models", () => { const { Test } = (await testHost.compile("main.tsp")) as { Test: Model; }; - ok(isRecordModelType(testHost.program, Test)); + ok(isRecordModelType(Test)); strictEqual(Test.indexer?.key.name, "string"); strictEqual(Test.indexer?.value.kind, "Scalar"); strictEqual(Test.indexer?.value.name, "int32"); @@ -1143,7 +1143,7 @@ describe("compiler: models", () => { const { Test } = (await testHost.compile("main.tsp")) as { Test: Model; }; - ok(isRecordModelType(testHost.program, Test)); + ok(isRecordModelType(Test)); const nameProp = Test.properties.get("name"); strictEqual(nameProp?.type.kind, "Scalar"); strictEqual(nameProp?.type.name, "string"); @@ -1165,7 +1165,7 @@ describe("compiler: models", () => { const { Test } = (await testHost.compile("main.tsp")) as { Test: Model; }; - ok(isRecordModelType(testHost.program, Test)); + ok(isRecordModelType(Test)); strictEqual(Test.indexer?.key.name, "string"); const indexerValue = Test.indexer?.value; strictEqual(indexerValue.kind, "Union"); diff --git a/packages/http-server-csharp/src/lib/attributes.ts b/packages/http-server-csharp/src/lib/attributes.ts index e45ded309b2..5c8bdf7e8b2 100644 --- a/packages/http-server-csharp/src/lib/attributes.ts +++ b/packages/http-server-csharp/src/lib/attributes.ts @@ -308,7 +308,7 @@ export function getArrayConstraintAttribute( const maxItems = getMaxItems(program, type); if (minItems === undefined && maxItems === undefined) return undefined; if (type.kind !== "ModelProperty" || type.type.kind !== "Model") return undefined; - if (!isArrayModelType(program, type.type)) return undefined; + if (!isArrayModelType(type.type)) return undefined; const arrayType = type.type; const elementType = arrayType.indexer.value; if (elementType.kind !== "Scalar") return undefined; diff --git a/packages/http-server-csharp/src/lib/type-helpers.ts b/packages/http-server-csharp/src/lib/type-helpers.ts index 487cd76be6f..acea1f70c23 100644 --- a/packages/http-server-csharp/src/lib/type-helpers.ts +++ b/packages/http-server-csharp/src/lib/type-helpers.ts @@ -70,11 +70,7 @@ export function getEnumType(en: Enum): EnumValueType | undefined { * @returns true if the type is an array or a model property with array type, otherwise false */ export function isArrayType(program: Program, type: ModelProperty | Scalar): boolean { - return ( - type.kind === "ModelProperty" && - type.type.kind === "Model" && - isArrayModelType(program, type.type) - ); + return type.kind === "ModelProperty" && type.type.kind === "Model" && isArrayModelType(type.type); } /** Inner representation of s string constraint */ diff --git a/packages/http-server-csharp/src/lib/utils.ts b/packages/http-server-csharp/src/lib/utils.ts index cd91b01a4ca..6926dc3a609 100644 --- a/packages/http-server-csharp/src/lib/utils.ts +++ b/packages/http-server-csharp/src/lib/utils.ts @@ -1586,7 +1586,7 @@ export class CSharpOperationHelpers { nullableType: false, hasUniqueItems: hasUniqueItems, }; - } else if (isArrayModelType(program, tsType)) { + } else if (isArrayModelType(tsType)) { const typeReference = code`${this.emitter.emitTypeReference(tsType.indexer.value)}`; modelResult = isByteType(tsType.indexer.value) ? { diff --git a/packages/http-server-js/src/common/reference.ts b/packages/http-server-js/src/common/reference.ts index 0d2f6456ebd..aef2620ab84 100644 --- a/packages/http-server-js/src/common/reference.ts +++ b/packages/http-server-js/src/common/reference.ts @@ -73,7 +73,7 @@ export function emitTypeReference( return getJsScalar(ctx, module, type, position).type; case "Model": { // First handle arrays. - if (isArrayModelType(ctx.program, type)) { + if (isArrayModelType(type)) { const argumentType = type.indexer.value; const argTypeReference = emitTypeReference(ctx, argumentType, position, module, { diff --git a/packages/http-server-js/src/common/serialization/json.ts b/packages/http-server-js/src/common/serialization/json.ts index 4b215597246..51f1d852012 100644 --- a/packages/http-server-js/src/common/serialization/json.ts +++ b/packages/http-server-js/src/common/serialization/json.ts @@ -64,7 +64,7 @@ export function requiresJsonSerialization( switch (type.kind) { case "Model": { - if (isArrayModelType(ctx.program, type)) { + if (isArrayModelType(type)) { const argumentType = type.indexer.value; requiresSerialization = requiresJsonSerialization(ctx, module, argumentType); break; @@ -237,7 +237,7 @@ export function transposeExpressionToJson( ): string { switch (type.kind) { case "Model": { - if (isArrayModelType(ctx.program, type)) { + if (isArrayModelType(type)) { const argumentType = type.indexer.value; if (requiresJsonSerialization(ctx, module, argumentType)) { @@ -245,7 +245,7 @@ export function transposeExpressionToJson( } else { return expr; } - } else if (isRecordModelType(ctx.program, type)) { + } else if (isRecordModelType(type)) { const argumentType = type.indexer.value; if (requiresJsonSerialization(ctx, module, argumentType)) { @@ -480,7 +480,7 @@ export function transposeExpressionFromJson( ): string { switch (type.kind) { case "Model": { - if (isArrayModelType(ctx.program, type)) { + if (isArrayModelType(type)) { const argumentType = type.indexer.value; if (requiresJsonSerialization(ctx, module, argumentType)) { @@ -488,7 +488,7 @@ export function transposeExpressionFromJson( } else { return expr; } - } else if (isRecordModelType(ctx.program, type)) { + } else if (isRecordModelType(type)) { const argumentType = type.indexer.value; if (requiresJsonSerialization(ctx, module, argumentType)) { diff --git a/packages/http-server-js/src/ctx.ts b/packages/http-server-js/src/ctx.ts index edc74f28695..0f2cb275064 100644 --- a/packages/http-server-js/src/ctx.ts +++ b/packages/http-server-js/src/ctx.ts @@ -47,9 +47,7 @@ export type DeclarationType = Model | Enum | Union | Interface | Scalar; */ export function isImportableType(ctx: JsContext, t: Type): t is DeclarationType { return ( - (t.kind === "Model" && - !isArrayModelType(ctx.program, t) && - !isRecordModelType(ctx.program, t)) || + (t.kind === "Model" && !isArrayModelType(t) && !isRecordModelType(t)) || t.kind === "Enum" || t.kind === "Interface" ); diff --git a/packages/http-server-js/src/http/server/index.ts b/packages/http-server-js/src/http/server/index.ts index a54351ccc7b..a2e1154f8b5 100644 --- a/packages/http-server-js/src/http/server/index.ts +++ b/packages/http-server-js/src/http/server/index.ts @@ -250,7 +250,7 @@ function* emitRawServerOperation( let value: string; if (requiresJsonSerialization(ctx, module, body.type)) { - if (body.type.kind === "Model" && isArrayModelType(ctx.program, body.type)) { + if (body.type.kind === "Model" && isArrayModelType(body.type)) { yield ` const __arrayBody = JSON.parse(body);`; yield ` if (!Array.isArray(__arrayBody)) {`; yield ` ${names.ctx}.errorHandlers.onInvalidRequest(`; @@ -261,7 +261,7 @@ function* emitRawServerOperation( yield ` return reject();`; yield ` }`; value = transposeExpressionFromJson(ctx, body.type, `__arrayBody`, module); - } else if (body.type.kind === "Model" && isRecordModelType(ctx.program, body.type)) { + } else if (body.type.kind === "Model" && isRecordModelType(body.type)) { yield ` const __recordBody = JSON.parse(body);`; yield ` if (typeof __recordBody !== "object" || __recordBody === null) {`; yield ` ${names.ctx}.errorHandlers.onInvalidRequest(`; @@ -641,7 +641,7 @@ function* emitResultProcessingForType( } else { yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}.${bodyCase.camelCase}));`; } - } else if (isArrayModelType(ctx.program, target)) { + } else if (isArrayModelType(target)) { const itemType = target.indexer.value; const serializationRequired = isSerializationRequired( @@ -659,7 +659,7 @@ function* emitResultProcessingForType( } else { yield `${names.ctx}.response.end(globalThis.JSON.stringify(${names.result}));`; } - } else if (isRecordModelType(ctx.program, target)) { + } else if (isRecordModelType(target)) { const itemType = target.indexer.value; const serializationRequired = isSerializationRequired( diff --git a/packages/http-server-js/src/util/differentiate.ts b/packages/http-server-js/src/util/differentiate.ts index d0cea95ea44..0cf18ebd514 100644 --- a/packages/http-server-js/src/util/differentiate.ts +++ b/packages/http-server-js/src/util/differentiate.ts @@ -676,7 +676,7 @@ export function differentiateModelTypes( let arrayVariant: Model | undefined = undefined; for (const model of models) { - if (isArrayModelType(ctx.program, model) && model.properties.size === 0 && !arrayVariant) { + if (isArrayModelType(model) && model.properties.size === 0 && !arrayVariant) { arrayVariant = model; continue; } diff --git a/packages/http/src/experimental/merge-patch/helpers.ts b/packages/http/src/experimental/merge-patch/helpers.ts index 6966362e290..6780ec33ab3 100644 --- a/packages/http/src/experimental/merge-patch/helpers.ts +++ b/packages/http/src/experimental/merge-patch/helpers.ts @@ -56,7 +56,7 @@ export function getMergePatchProperties( function getUpdateBehavior(type: Type): "merge" | "replace" { switch (type.kind) { case "Model": - if (isArrayModelType(program, type)) return "merge"; + if (isArrayModelType(type)) return "merge"; return "replace"; default: return "replace"; diff --git a/packages/http/src/payload.ts b/packages/http/src/payload.ts index aa958b94078..d69d68b57a2 100644 --- a/packages/http/src/payload.ts +++ b/packages/http/src/payload.ts @@ -133,7 +133,7 @@ function resolveBody( } // non-model or intrinsic/array model -> response body is response type - if (requestOrResponseType.kind !== "Model" || isArrayModelType(program, requestOrResponseType)) { + if (requestOrResponseType.kind !== "Model" || isArrayModelType(requestOrResponseType)) { return diagnostics.wrap({ bodyKind: "single", ...diagnostics.pipe( @@ -516,7 +516,7 @@ function resolvePartOrParts( visibility: Visibility, property?: ModelProperty, ): DiagnosticResult { - if (type.kind === "Model" && isArrayModelType(program, type)) { + if (type.kind === "Model" && isArrayModelType(type)) { const [part, diagnostics] = resolvePart(program, type.indexer.value, visibility, property); if (part) { return [{ ...part, multi: true }, diagnostics]; diff --git a/packages/openapi3/src/schema-emitter.ts b/packages/openapi3/src/schema-emitter.ts index 0de31296758..a6970792702 100644 --- a/packages/openapi3/src/schema-emitter.ts +++ b/packages/openapi3/src/schema-emitter.ts @@ -455,7 +455,7 @@ export class OpenAPI3SchemaEmitterBase< } } - if (schema && isRef && !(prop.type.kind === "Model" && isArrayModelType(program, prop.type))) { + if (schema && isRef && !(prop.type.kind === "Model" && isArrayModelType(prop.type))) { if (Object.keys(additionalProps).length === 0) { return schema; } else { diff --git a/packages/openapi3/src/xml-module.ts b/packages/openapi3/src/xml-module.ts index 7b487339cf6..5d6b4237788 100644 --- a/packages/openapi3/src/xml-module.ts +++ b/packages/openapi3/src/xml-module.ts @@ -108,7 +108,7 @@ export async function resolveXmlModule(): Promise { // Handle array wrapping if necessary const hasUnwrappedDecorator = xml.isUnwrapped(program, prop); - const isArrayProperty = prop.type?.kind === "Model" && isArrayModelType(program, prop.type); + const isArrayProperty = prop.type?.kind === "Model" && isArrayModelType(prop.type); if (!isArrayProperty && hasUnwrappedDecorator) { reportDiagnostic(program, { code: "xml-unwrapped-invalid-property-type", @@ -188,7 +188,7 @@ function isXmlModelChecker( } if (model.kind === "ModelProperty") { - const isArrayProperty = model.type?.kind === "Model" && isArrayModelType(program, model.type); + const isArrayProperty = model.type?.kind === "Model" && isArrayModelType(model.type); if (isArrayProperty) { const propValue = (model.type as ArrayModelType).indexer.value; if (propValue.kind === "Scalar") { @@ -213,7 +213,7 @@ function isXmlModelChecker( return true; } - if (prop.type?.kind === "Model" && isArrayModelType(program, prop.type)) { + if (prop.type?.kind === "Model" && isArrayModelType(prop.type)) { const propValue = (prop.type as ArrayModelType).indexer.value; const propModel = propValue as Model; if (propModel && !checked.includes(propModel.name)) { diff --git a/packages/samples/specs/rest-metadata-emitter/rest-metadata-emitter-sample.ts b/packages/samples/specs/rest-metadata-emitter/rest-metadata-emitter-sample.ts index 046f6581dfd..57e57bde645 100644 --- a/packages/samples/specs/rest-metadata-emitter/rest-metadata-emitter-sample.ts +++ b/packages/samples/specs/rest-metadata-emitter/rest-metadata-emitter-sample.ts @@ -199,7 +199,7 @@ export async function $onEmit(context: EmitContext): Promise { } break; case "Model": - if (isArrayModelType(program, type)) { + if (isArrayModelType(type)) { // When a model appears in an array, we add the special Item to include // all metadata in payload. visibility |= Visibility.Item; @@ -232,7 +232,7 @@ export async function $onEmit(context: EmitContext): Promise { ): string { const remarks: string[] = []; - if (property.type.kind === "Model" && isArrayModelType(program, property.type)) { + if (property.type.kind === "Model" && isArrayModelType(property.type)) { remarks.push("+Item on element visibility"); } diff --git a/packages/tspd/src/gen-extern-signatures/components/decorator-signature-type.tsx b/packages/tspd/src/gen-extern-signatures/components/decorator-signature-type.tsx index 6be3b79168e..58d98921bb5 100644 --- a/packages/tspd/src/gen-extern-signatures/components/decorator-signature-type.tsx +++ b/packages/tspd/src/gen-extern-signatures/components/decorator-signature-type.tsx @@ -74,14 +74,14 @@ function extractRestParamConstraint( let valueType: Type | undefined; let type: Type | undefined; if (constraint.valueType) { - if (constraint.valueType.kind === "Model" && isArrayModelType(program, constraint.valueType)) { + if (constraint.valueType.kind === "Model" && isArrayModelType(constraint.valueType)) { valueType = constraint.valueType.indexer.value; } else { return undefined; } } if (constraint.type) { - if (constraint.type.kind === "Model" && isArrayModelType(program, constraint.type)) { + if (constraint.type.kind === "Model" && isArrayModelType(constraint.type)) { type = constraint.type.indexer.value; } else { return undefined; @@ -178,7 +178,6 @@ function getCompilerType(name: string) { } function ValueTsType({ type }: { type: Type }) { - const { program } = useTspd(); switch (type.kind) { case "Boolean": return `${type.value}`; @@ -194,7 +193,7 @@ function ValueTsType({ type }: { type: Type }) { { joiner: " | " }, ); case "Model": - if (isArrayModelType(program, type)) { + if (isArrayModelType(type)) { return ( <> readonly (