Recently, I have been delving into the realm of Javascript/Typescript/React as a PHP developer.
During my learning process, I encountered a few perplexing issues that I could not fully grasp.
In light of this, I am reaching out to the experienced individuals here for some guidance.
#1 Creating a Generic Function with Mongoose Model as a Generic Type
Description
I devised a generic function to retrieve all schema properties excluding _id and __v fields.
After several attempts, I managed to get it working. Below is the code snippet:
// model
import mongoose, { Schema, Document } from 'mongoose'
export interface IGenre extends Document {
name: string,
description: string,
createdDate: Date,
updatedDate: Date
}
const GenreSchema: Schema = new Schema({
name: { type: String, default: '' },
description: { type: String, default: '' },
createdDate: { type: Date, default: Date.now },
updatedDate: { type: Date, default: Date.now }
})
export default mongoose.models['Genre'] || mongoose.model<IGenre>('Genre', GenreSchema)
// generic function returning props of model
import { Model } from 'mongoose'
const getSchemaProps = <S extends Model<S>>(s: S): string[] => {
return Object.keys(s.schema.paths).filter(p => p !== '_id' && p !== '__v')
}
export {
getSchemaProps,
}
Unclear Concept
The part that puzzles me is <S extends Model<S>>
.
Aren't we creating some sort of loop here?
My understanding is that S extends Model, but the S inside Model also extends Model, resulting in
S extends Model<S extends Model<S....>>
I did not search Google for an explanation, just experimented randomly and it surprisingly worked without any errors!
Inquiry
Why does this particular line of code not raise an error?
<S extends Model<S>>
#2 Extending Types with Assigned Values
Description
While browsing through the type definition file of a Material UI component, I stumbled upon a syntax that left me baffled.
// <system_path>\node_modules\@mui\x-data-grid\models\colDef\gridColDef.d.ts
export declare type GridColumns<R extends GridValidRowModel = any> = GridEnrichedColDef<R>[]
The definition of GridValidRowModel
can be found below in this same file:
// <system_path>\node_modules\@mui\x-data-grid\models\gridRows.d.ts
export declare type GridValidRowModel = {
[key: string]: any;
};
Confusion
Upon reading the TypeScript documentation, I was unable to find an explanation for the following syntax:
GridColumns<R extends GridValidRowModel = any> // (1)
If I were to hazard a guess, the GridValidRowModel = any
part assigns a default type of any to GridValidRowModel
, making (1) equivalent to this:
GridColumns<R extends any>
However, in gridRows.d.ts
, GridValidRowModel
is clearly defined as an object with key-value properties.
Question
What exactly does this syntax signify?
ISomeInterface<T extends A = B>
In the given code snippet, what type of R is being referred to?