@@ -247,6 +247,118 @@ mod test {
247247 ) ) ;
248248 }
249249
250+ #[ test]
251+ fn test_alias_keyof_constraint_accepts_keyof_type ( ) {
252+ let mut ws = VirtualWorkspace :: new ( ) ;
253+ assert ! ( ws. has_no_diagnostic(
254+ DiagnosticCode :: GenericConstraintMismatch ,
255+ r#"
256+ ---@class A
257+ ---@field one 1
258+ ---@field two 2
259+ ---@field three 3
260+
261+ ---@alias C<K extends keyof A> any
262+
263+ ---@type C<keyof A>
264+ local tmp
265+ "# ,
266+ ) ) ;
267+ }
268+
269+ #[ test]
270+ fn test_alias_keyof_constraint_rejects_keyof_type_with_invalid_key ( ) {
271+ let mut ws = VirtualWorkspace :: new ( ) ;
272+ assert ! ( !ws. has_no_diagnostic(
273+ DiagnosticCode :: GenericConstraintMismatch ,
274+ r#"
275+ ---@class A
276+ ---@field one 1
277+ ---@field two 2
278+
279+ ---@class B
280+ ---@field one 1
281+ ---@field missing 3
282+
283+ ---@alias C<K extends keyof A> any
284+
285+ ---@type C<keyof B>
286+ local tmp
287+ "# ,
288+ ) ) ;
289+ }
290+
291+ #[ test]
292+ fn test_alias_keyof_constraint_rejects_invalid_union_for_keyof_type ( ) {
293+ let mut ws = VirtualWorkspace :: new ( ) ;
294+ assert ! ( !ws. has_no_diagnostic(
295+ DiagnosticCode :: GenericConstraintMismatch ,
296+ r#"
297+ ---@class A
298+ ---@field one 1
299+ ---@field two 2
300+
301+ ---@alias C<K extends keyof A> any
302+
303+ ---@type C<'one' | 'missing'>
304+ local tmp
305+ "# ,
306+ ) ) ;
307+ }
308+
309+ #[ test]
310+ fn test_alias_dependent_keyof_constraint_uses_explicit_type_arg ( ) {
311+ let mut ws = VirtualWorkspace :: new ( ) ;
312+ assert ! ( ws. has_no_diagnostic(
313+ DiagnosticCode :: GenericConstraintMismatch ,
314+ r#"
315+ ---@class Base
316+ ---@field common 1
317+
318+ ---@class Exact: Base
319+ ---@field one 1
320+ ---@field two 2
321+
322+ ---@alias PickFrom<T extends Base, K extends keyof T> any
323+
324+ ---@type PickFrom<Exact, keyof Exact>
325+ local tmp
326+ "# ,
327+ ) ) ;
328+
329+ assert ! ( !ws. has_no_diagnostic(
330+ DiagnosticCode :: GenericConstraintMismatch ,
331+ r#"
332+ ---@type PickFrom<Exact, 'error'>
333+ local tmp
334+ "# ,
335+ ) ) ;
336+ }
337+
338+ #[ test]
339+ fn test_alias_dependent_keyof_constraint_rejects_keyof_other_type ( ) {
340+ let mut ws = VirtualWorkspace :: new ( ) ;
341+ assert ! ( !ws. has_no_diagnostic(
342+ DiagnosticCode :: GenericConstraintMismatch ,
343+ r#"
344+ ---@class Base
345+ ---@field common 1
346+
347+ ---@class Exact: Base
348+ ---@field one 1
349+
350+ ---@class Extra: Base
351+ ---@field one 1
352+ ---@field missing 2
353+
354+ ---@alias PickFrom<T extends Base, K extends keyof T> any
355+
356+ ---@type PickFrom<Exact, keyof Extra>
357+ local tmp
358+ "# ,
359+ ) ) ;
360+ }
361+
250362 #[ test]
251363 fn test_alias_keyof_constraint_rejects_union_with_invalid_key ( ) {
252364 let mut ws = VirtualWorkspace :: new ( ) ;
@@ -345,6 +457,40 @@ mod test {
345457 ) ) ;
346458 }
347459
460+ #[ test]
461+ fn test_dependent_keyof_default_must_satisfy_any_valid_type_arg ( ) {
462+ let mut ws = VirtualWorkspace :: new ( ) ;
463+ assert ! ( !ws. has_no_diagnostic(
464+ DiagnosticCode :: GenericConstraintMismatch ,
465+ r#"
466+ ---@class Base
467+ ---@field common 1
468+
469+ ---@class Exact: Base
470+ ---@field one 1
471+
472+ ---@alias PickFrom<T extends Base = Exact, K extends keyof T = keyof Exact> any
473+ "# ,
474+ ) ) ;
475+ }
476+
477+ #[ test]
478+ fn test_dependent_keyof_default_can_reference_same_type_param ( ) {
479+ let mut ws = VirtualWorkspace :: new ( ) ;
480+ assert ! ( ws. has_no_diagnostic(
481+ DiagnosticCode :: GenericConstraintMismatch ,
482+ r#"
483+ ---@class Base
484+ ---@field common 1
485+
486+ ---@class Exact: Base
487+ ---@field one 1
488+
489+ ---@alias PickFrom<T extends Base = Exact, K extends keyof T = keyof T> any
490+ "# ,
491+ ) ) ;
492+ }
493+
348494 #[ test]
349495 fn test_alias_generic_default_constraint_mismatch ( ) {
350496 let mut ws = VirtualWorkspace :: new ( ) ;
0 commit comments