{"record":{"id":"051b36661b8865ef","repo":"can1357/oh-my-pi","slug":"parameter-name-must-be-assignable-to-its-constr","errorCode":null,"errorMessage":"${parameter.name} must be assignable to its constraint","messagePattern":"(.+?) must be assignable to its constraint","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/type.ts","lineNumber":2649,"sourceCode":"\tvalidateGenericParameters(parameters);\n\tconst placeholders = parameters.map(parameter =>\n\t\tparameter.constraintDef === undefined\n\t\t\t? ({ k: \"unknown\" } as IR)\n\t\t\t: parseDef(parameter.constraintDef, constraintResolve),\n\t);\n\tif (validateBody) genericBodyIR(parameters, definition, placeholders, outer);\n\tconst meta: GenericMeta = {\n\t\tparameters,\n\t\tinstantiateIR(arguments_) {\n\t\t\tif (arguments_.length !== parameters.length) {\n\t\t\t\tthrow new OmpTypeError(`generic expects ${parameters.length} arguments (received ${arguments_.length})`);\n\t\t\t}\n\t\t\tfor (let index = 0; index < parameters.length; index++) {\n\t\t\t\tconst parameter = parameters[index];\n\t\t\t\tif (parameter.constraintDef === undefined) continue;\n\t\t\t\tconst constraint = parseDef(parameter.constraintDef, constraintResolve);\n\t\t\t\tif (!isSubtype(arguments_[index], constraint)) {\n\t\t\t\t\tthrow new OmpTypeError(`${parameter.name} must be assignable to its constraint`);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn genericBodyIR(parameters, definition, arguments_, outer);\n\t\t},\n\t};\n\tconst generic = Object.assign(\n\t\t(...arguments_: readonly unknown[]) =>\n\t\t\tmakeType(\n\t\t\t\tmeta.instantiateIR(arguments_.map(argument => parseGenericArgument(argument, outer))),\n\t\t\t\tEMPTY_STEPS,\n\t\t\t\tEMPTY_META,\n\t\t\t),\n\t\t{ [GENERIC_META]: meta },\n\t);\n\tObject.defineProperty(generic, GENERIC_META, { value: meta });\n\treturn generic;\n}\n","sourceCodeStart":2631,"sourceCodeEnd":2667,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/type.ts#L2631-L2667","documentation":"When instantiating a generic with constraint declarations, each argument is checked with isSubtype against its parameter's constraint; a violating argument throws OmpTypeError. Constraints restrict what type arguments are admissible, mirroring TypeScript's 'T extends X'.","triggerScenarios":"Instantiating a constrained generic with a type that isn't assignable to the constraint, e.g. generic('<T extends number>', 'T[]') instantiated with 'string'; the constraintDef is parsed and isSubtype(argument, constraint) returns false.","commonSituations":"Passing a broader type (string) where a narrower one (a literal union or number) is constrained; swapping argument order in a multi-parameter generic so the wrong argument meets the wrong constraint; loosening the body but not the constraint (or vice versa) during refactors.","solutions":["Pass a type argument that satisfies the constraint (e.g. 'number' or a numeric literal for 'T extends number')","Verify argument order matches parameter order in multi-parameter generics","If the constraint is too strict for your use case, widen the declared constraint","Pre-validate with isSubtype(argument, constraint) yourself before instantiating to give a better message"],"exampleFix":"// before\nconst G = generic('<T extends number>', 'T[]');\nconst a = G('string'); // throws\n// after\nconst a = G('number');","handlingStrategy":"validation","validationCode":"import { isSubtype, type } from '@oh-my-pi/omptype';\nfunction assertSatisfies(arg: unknown, constraintDef: string, name: string) {\n  const constraint = type(constraintDef);\n  if (!isSubtype(arg, constraint)) {\n    throw new Error(`${name} must satisfy constraint ${constraintDef}`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const inst = G(arg);\n} catch (err) {\n  if (err instanceof OmpTypeError && err.message.includes('must be assignable to its constraint')) {\n    throw new Error(`Argument for ${err.message.split(' ')[0]} violates its constraint — widen the constraint or pass a narrower type`);\n  }\n  throw err;\n}","preventionTips":["Read each parameter's constraint before choosing arguments","Keep parameter order in mind for multi-parameter generics","Pre-check arguments with isSubtype during development"],"tags":["generics","constraints","type-safety","omptype"],"backgroundTag":"type-constraint-violation","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}