@@ -93,7 +93,7 @@ export const getSignatureSchema = (
9393 )
9494
9595 // Identify parameter dependencies based on type parameters
96- const funktionDependencies = getParameterDependencies ( funktion ! )
96+ const funktionDependencies = getParameterDependencies ( funktion ! , nodeParameterTypes )
9797
9898 // Generate schema for each parameter
9999 return generateNodeSchemas (
@@ -203,30 +203,57 @@ const extractFunctionParameterTypes = (
203203/**
204204 * Identifies parameter dependencies based on shared type parameters.
205205 * Determines which parameters depend on type parameters declared in other parameters.
206+ * If an argument is explicitly provided (not null/undefined), it is not blocked.
206207 *
207- * @param node - The function declaration to analyze
208+ * @param funktion - The function declaration to analyze
209+ * @param nodeParameterTypes
208210 * @returns Array of ParameterDependency objects
209211 */
210- const getParameterDependencies = ( node : ts . FunctionDeclaration ) : ParameterDependency [ ] => {
211- // Extract all type parameter names from the function
212- const typeParamNames = node . typeParameters ?. map ( ( tp ) => tp . name . getText ( ) ) || [ ]
212+ const getParameterDependencies = (
213+ funktion : ts . FunctionDeclaration ,
214+ nodeParameterTypes : ts . Type [ ] | undefined
215+ ) : ParameterDependency [ ] => {
216+ const typeParamNames = funktion . typeParameters ?. map ( ( tp ) => tp . name . getText ( ) ) || [ ]
213217 const usage : Record < string , number [ ] > = { }
214218
215219 // Track which parameters use each type parameter
216- node . parameters . forEach ( ( p , i ) => {
217- const typeText = p . type ?. getText ( ) || ""
218- typeParamNames . forEach ( ( typeParam ) => {
219- if ( typeText . includes ( typeParam ) ) {
220- if ( ! usage [ typeParam ] ) {
221- usage [ typeParam ] = [ ]
220+ funktion . parameters . forEach ( ( p , i ) => {
221+ if ( ! p . type ) return
222+
223+ // Ein Set, um Duplikate pro Parameter zu vermeiden (falls 'A' mehrfach im selben Param-Typ vorkommt)
224+ const foundInParameter = new Set < string > ( )
225+
226+ // Wir laufen rekursiv durch den Typ-Knoten des Parameters
227+ p . type . forEachChild ( function visitor ( child ) {
228+ // Sucht nach expliziten Typ-Referenzen (z.B. die Typen in den <...> oder der Typ selbst)
229+ if ( ts . isTypeReferenceNode ( child ) && ts . isIdentifier ( child . typeName ) ) {
230+ const typeName = child . typeName . text
231+ if ( typeParamNames . includes ( typeName ) ) {
232+ foundInParameter . add ( typeName )
233+ }
234+ }
235+ // Falls der Typ selbst nur der Typparameter ist (z.B. p.type ist direkt ein TypeReferenceNode)
236+ if ( ts . isTypeReferenceNode ( p . type ! ) && ts . isIdentifier ( p . type . typeName ) ) {
237+ const directTypeName = p . type . typeName . text
238+ if ( typeParamNames . includes ( directTypeName ) ) {
239+ foundInParameter . add ( directTypeName )
222240 }
223- usage [ typeParam ] . push ( i )
224241 }
242+
243+ child . forEachChild ( visitor )
244+ } )
245+
246+ // Gefundene Abhängigkeiten für diesen Parameter registrieren
247+ foundInParameter . forEach ( ( typeParam ) => {
248+ if ( ! usage [ typeParam ] ) {
249+ usage [ typeParam ] = [ ]
250+ }
251+ usage [ typeParam ] . push ( i )
225252 } )
226253 } )
227254
228- // Extract dependencies: type params used by multiple parameters
229- return Object . values ( usage )
255+ // Extract raw dependencies based on type definition
256+ const rawDependencies = Object . values ( usage )
230257 . filter ( ( indices ) => indices . length > 1 )
231258 . map ( ( [ firstIndex , ...otherIndices ] ) =>
232259 otherIndices . map ( ( depIndex ) => ( {
@@ -235,8 +262,28 @@ const getParameterDependencies = (node: ts.FunctionDeclaration): ParameterDepend
235262 } ) ) ,
236263 )
237264 . flat ( )
238- }
239265
266+ // Wenn wir keine Typen vom Checker haben, bleiben wir beim Standard
267+ if ( ! nodeParameterTypes ) {
268+ return rawDependencies
269+ }
270+
271+ // Filter heraus, was durch echte Werte (nicht null/undefined) bereits aufgelöst ist
272+ return rawDependencies . filter ( ( dep ) => {
273+ const resolvedType = nodeParameterTypes [ dep . parameterIndex ]
274+
275+ // Falls aus irgendeinem Grund kein Typ ermittelt werden konnte -> blocked lassen
276+ if ( ! resolvedType ) return true
277+
278+ // Prüfen, ob der Typ null oder undefined ist
279+ const isNull = ( resolvedType . flags & ts . TypeFlags . Null ) !== 0
280+ const isUndefined = ( resolvedType . flags & ts . TypeFlags . Undefined ) !== 0
281+
282+ // Wenn es null oder undefined IST, bleibt es blocked (true)
283+ // Wenn es ein echter Wert ist, fliegt die Dependency raus (false)
284+ return isNull || isUndefined
285+ } )
286+ }
240287/**
241288 * Generates node schemas for all parameters.
242289 * Creates schema objects for each parameter with their dependencies.
0 commit comments