Issue
I'm a php developer and am trying to learn js/typescript/react lately.
I've stumbled upon a few issues that I didn't quite understand.
So I make this thread with the hope that some experienced people will help me out.
#1 Generic function with mongoose model as generic type
Description
I write a generic function that returns all properties of a schema except for _id and __v.
After a few tries, I was able to make it work, here's my code:
// 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,
}
What I don't understand
The part I don't understand is <S extends Model<S>>
.
Doesn't this create some kind of a loop?
Like S extends Model, but the S inside Model extends Model as well, according to my understanding, which results in S extends Model<S extends Model<S....>>
I didn't look up google for this solution, just applied random changes and it worked without throwing any errors!
Question
Why doesn't this line of code throw error?
<S extends Model<S>>
#2 Type extending with assigned value
Description
When looking up the type definition file of material ui component, there was a syntax I couldn't understand.
// <system_path>\node_modules\@mui\x-data-grid\models\colDef\gridColDef.d.ts
export declare type GridColumns<R extends GridValidRowModel = any> = GridEnrichedColDef<R>[]
GridValidRowModel
is defined in this file below
// <system_path>\node_modules\@mui\x-data-grid\models\gridRows.d.ts
export declare type GridValidRowModel = {
[key: string]: any;
};
What I don't understand
I read typescript doc, maybe I missed it but I just can't find anywhere explaining this syntax:
GridColumns<R extends GridValidRowModel = any> // (1)
If I have to guess the GridValidRowModel = any
part assigns a default any type to GridValidRowModel
, which makes (1) equivalent to this:
GridColumns<R extends any>
But in gridRows.d.ts
GridValidRowModel
is clearly defined as an Object with key:value properties.
Question
What does this syntax mean?
ISomeInterface<T extends A = B>
What type of R is in the code above?
Solution
You are parsing the generics wrong - I have added paranthesis for emphasis
What you read is
ISomeInterface<T extends (A = B)>
What Typescript reads is
ISomeInterface<(T extends A) = B>
That means that
GridColumns<R extends GridValidRowModel = any>
is equivalent to
GridColumns<any>
Note that 'any' does not mean an empty object but rather something that will fulfill any class checks - 'any' will extend everything!
Answered By - Arne Bergene Fossaa
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.