Explore the Unique Playground
Given a specific type:
export declare type CustomFilter<T> = {
[P in keyof T]?: (P extends keyof T ? T[P] : any);
};
Encountering an issue when defining the filter as follows:
update.$setOnInsert.createdAt = new Date();
An error is thrown stating:
Type 'Date' is not assignable to type '"createdAt" extends keyof T ? T[keyof T & "createdAt"] : any'.ts(2322)
The problem disappears if the filter is changed to:
export declare type CustomFilter<T> = {
[P in keyof T]?: any;
};
The question arises as to why the conditional statement does not deduce the correct type and instead retains the code portion.
Although there may be other issues with the filter structure, the core problem lies in conditional statements failing to ascertain the actual type.
Detailed Example
interface DocumentCollection {
_id?: string;
createdAt: Date;
}
type PathImpl<T, Key extends keyof T> =
Key extends string
? T[Key] extends Record<string, any>
? `${Key}.${PathImpl<T[Key], Exclude<keyof T[Key], keyof Date | keyof Object | keyof string> & string>}`
| `${Key}.${Exclude<keyof T[Key], keyof Date | keyof Object | keyof string> & string}`
: never
: never;
type Path<T> = keyof T | PathImpl<T, keyof T>;
type PathValue<T, P extends Path<T>> =
P extends `${infer Key}.${infer Rest}`
? Key extends keyof T
? Rest extends Path<T[Key]>
? PathValue<T[Key], Rest>
: never
: never
: P extends keyof T
? T[P]
: any;
export declare type CustomFilter<T> = {
[P in Path<T>]?: PathValue<T, P>;
};
export class CustomCollection<T extends DocumentCollection> {
constructor() {}
updateOne(filter: CustomFilter<T>) {
// ISSUE OCCURS HERE
filter._id = '';
filter.createdAt = new Date();
}
}
// THIS FUNCTION IS WORKING AS EXPECTED
let testModel = new CustomCollection<DocumentCollection>();
testModel.updateOne({_id: 'test', createdAt: new Date()});
Additional complexities have been added to the playground scenario leading to further similar challenges:
Navigate through the Enhanced Playground
A recursive type implementation seems to trigger this error:
Type instantiation is excessively deep and possibly infinite.ts(2589)