An update to dependencies in my TypeScript-based Nodejs project has led to compilation errors when working with a generic class that manages mongoose models. The root cause appears to be related to how TypeScript handles generic types.
To illustrate the issue, consider the following example:
interface I {
p: string;
}
class Foo<T extends I> {
exclude: Exclude<'p', 'q'> = 'p'; // Compilation passes
excludeI: Exclude<keyof I, 'q'> = 'p'; // Compilation passes
excludeT: Exclude<keyof T, 'q'> = 'p'; // Error: Type '"p"' is not assignable to type 'Exclude<keyof T, "q">'.
}
The difference between excludeI
(which compiles successfully) and excludeT
(resulting in a compile error) lies in using the generic type T
instead of the interface type I
.
Given that T
extends I
, it is expected that these two cases would be treated similarly. Surprisingly, the keyof
operator behaves consistently regardless of whether it's applied to T
or I
:
class Foo<T extends I> {
keyof: 'p' = 'p'; // Compilation passes
keyofI: keyof I = 'p'; // Compilation passes
keyofT: keyof T = 'p'; // Compilation passes
}
I used this TypeScript Playground example to test different TS versions, but the behavior remained consistent across versions.
If anyone can provide insight into the issue observed with Exclude<>, it would be greatly appreciated.