Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
public
/
sequelize
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
不要怂,就是干,撸起袖子干!
Commit 5cabcbc8
authored
Jul 04, 2020
by
Constantin Metz
Committed by
GitHub
Jul 04, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(types): Add ModelDefined type as syntactic sugar (#12445)
1 parent
4d82907d
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
97 additions
and
19 deletions
docs/manual/other-topics/typescript.md
types/lib/model.d.ts
types/test/typescriptDocs/ModelInit.ts
docs/manual/other-topics/typescript.md
View file @
5cabcbc
...
...
@@ -15,12 +15,13 @@ In order to avoid installation bloat for non TS users, you must install the foll
Example of a minimal TypeScript project with strict type-checking for attributes.
**NOTE:**
Keep the following code in sync with
`typescriptDocs/ModelInit.ts`
to ensure it typechecks correctly.
**NOTE:**
Keep the following code in sync with
`
/types/test/
typescriptDocs/ModelInit.ts`
to ensure it typechecks correctly.
```
ts
import
{
Sequelize
,
Model
,
ModelDefined
,
DataTypes
,
HasManyGetAssociationsMixin
,
HasManyAddAssociationMixin
,
...
...
@@ -104,6 +105,16 @@ class Address extends Model<AddressAttributes> implements AddressAttributes {
public
readonly
updatedAt
!
:
Date
;
}
// You can also define modules in a functional way
interface
NoteAttributes
{
id
:
number
;
title
:
string
;
content
:
string
;
}
// You can also set multiple attributes optional at once
interface
NoteCreationAttributes
extends
Optional
<
NoteAttributes
,
'id'
|
'title'
>
{};
Project
.
init
(
{
id
:
{
...
...
@@ -164,6 +175,32 @@ Address.init(
}
);
// And with a functional approach defining a module looks like this
const
Note
:
ModelDefined
<
NoteAttributes
,
NoteCreationAttributes
>
=
sequelize
.
define
(
'Note'
,
{
id
:
{
type
:
DataTypes
.
INTEGER
.
UNSIGNED
,
autoIncrement
:
true
,
primaryKey
:
true
,
},
title
:
{
type
:
new
DataTypes
.
STRING
(
64
),
defaultValue
:
'Unnamed Note'
,
},
content
:
{
type
:
new
DataTypes
.
STRING
(
4096
),
allowNull
:
false
,
},
},
{
tableName
:
'notes'
,
}
);
// Here we associate which actually populates out pre-declared `association` static and other methods.
User
.
hasMany
(
Project
,
{
sourceKey
:
"id"
,
...
...
types/lib/model.d.ts
View file @
5cabcbc
...
...
@@ -2849,6 +2849,8 @@ export type ModelType = typeof Model;
// must come first for unknown reasons.
export
type
ModelCtor
<
M
extends
Model
>
=
typeof
Model
&
{
new
():
M
};
export
type
ModelDefined
<
S
,
T
>
=
ModelCtor
<
Model
<
S
,
T
>>
;
export
type
ModelStatic
<
M
extends
Model
>
=
{
new
():
M
};
export
default
Model
;
types/test/typescriptDocs/ModelInit.ts
View file @
5cabcbc
...
...
@@ -4,6 +4,7 @@
import
{
Sequelize
,
Model
,
ModelDefined
,
DataTypes
,
HasManyGetAssociationsMixin
,
HasManyAddAssociationMixin
,
...
...
@@ -12,9 +13,9 @@ import {
HasManyCountAssociationsMixin
,
HasManyCreateAssociationMixin
,
Optional
,
}
from
'sequelize'
;
}
from
"sequelize"
;
const
sequelize
=
new
Sequelize
(
'mysql://root:asd123@localhost:3306/mydb'
);
const
sequelize
=
new
Sequelize
(
"mysql://root:asd123@localhost:3306/mydb"
);
// These are all the attributes in the User model
interface
UserAttributes
{
...
...
@@ -24,7 +25,7 @@ interface UserAttributes {
}
// Some attributes are optional in `User.build` and `User.create` calls
interface
UserCreationAttributes
extends
Optional
<
UserAttributes
,
'id'
>
{}
interface
UserCreationAttributes
extends
Optional
<
UserAttributes
,
"id"
>
{}
class
User
extends
Model
<
UserAttributes
,
UserCreationAttributes
>
implements
UserAttributes
{
...
...
@@ -60,7 +61,7 @@ interface ProjectAttributes {
name
:
string
;
}
interface
ProjectCreationAttributes
extends
Optional
<
ProjectAttributes
,
'id'
>
{}
interface
ProjectCreationAttributes
extends
Optional
<
ProjectAttributes
,
"id"
>
{}
class
Project
extends
Model
<
ProjectAttributes
,
ProjectCreationAttributes
>
implements
ProjectAttributes
{
...
...
@@ -87,6 +88,17 @@ class Address extends Model<AddressAttributes> implements AddressAttributes {
public
readonly
updatedAt
!
:
Date
;
}
// You can also define modules in a functional way
interface
NoteAttributes
{
id
:
number
;
title
:
string
;
content
:
string
;
}
// You can also set multiple attributes optional at once
interface
NoteCreationAttributes
extends
Optional
<
NoteAttributes
,
"id"
|
"title"
>
{}
Project
.
init
(
{
id
:
{
...
...
@@ -105,8 +117,8 @@ Project.init(
},
{
sequelize
,
tableName
:
'projects'
,
}
,
tableName
:
"projects"
,
}
);
User
.
init
(
...
...
@@ -126,9 +138,9 @@ User.init(
},
},
{
tableName
:
'users'
,
tableName
:
"users"
,
sequelize
,
// passing the `sequelize` instance is required
}
,
}
);
Address
.
init
(
...
...
@@ -142,30 +154,56 @@ Address.init(
},
},
{
tableName
:
'address'
,
tableName
:
"address"
,
sequelize
,
// passing the `sequelize` instance is required
}
);
// And with a functional approach defining a module looks like this
const
Note
:
ModelDefined
<
NoteAttributes
,
NoteCreationAttributes
>
=
sequelize
.
define
(
"Note"
,
{
id
:
{
type
:
DataTypes
.
INTEGER
.
UNSIGNED
,
autoIncrement
:
true
,
primaryKey
:
true
,
},
title
:
{
type
:
new
DataTypes
.
STRING
(
64
),
defaultValue
:
"Unnamed Note"
,
},
content
:
{
type
:
new
DataTypes
.
STRING
(
4096
),
allowNull
:
false
,
},
},
{
tableName
:
"notes"
,
}
);
// Here we associate which actually populates out pre-declared `association` static and other methods.
User
.
hasMany
(
Project
,
{
sourceKey
:
'id'
,
foreignKey
:
'ownerId'
,
as
:
'projects'
,
// this determines the name in `associations`!
sourceKey
:
"id"
,
foreignKey
:
"ownerId"
,
as
:
"projects"
,
// this determines the name in `associations`!
});
Address
.
belongsTo
(
User
,
{
targetKey
:
'id'
});
User
.
hasOne
(
Address
,
{
sourceKey
:
'id'
});
Address
.
belongsTo
(
User
,
{
targetKey
:
"id"
});
User
.
hasOne
(
Address
,
{
sourceKey
:
"id"
});
async
function
doStuffWithUser
()
{
const
newUser
=
await
User
.
create
({
name
:
'Johnny'
,
preferredName
:
'John'
,
name
:
"Johnny"
,
preferredName
:
"John"
,
});
console
.
log
(
newUser
.
id
,
newUser
.
name
,
newUser
.
preferredName
);
const
project
=
await
newUser
.
createProject
({
name
:
'first!'
,
name
:
"first!"
,
});
const
ourUser
=
await
User
.
findByPk
(
1
,
{
...
...
@@ -176,4 +214,4 @@ async function doStuffWithUser() {
// Note the `!` null assertion since TS can't know if we included
// the model or not
console
.
log
(
ourUser
.
projects
!
[
0
].
name
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment