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
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
95 additions
and
18 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
...
@@ -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.
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
```
ts
import
{
import
{
Sequelize
,
Sequelize
,
Model
,
Model
,
ModelDefined
,
DataTypes
,
DataTypes
,
HasManyGetAssociationsMixin
,
HasManyGetAssociationsMixin
,
HasManyAddAssociationMixin
,
HasManyAddAssociationMixin
,
...
@@ -104,6 +105,16 @@ class Address extends Model<AddressAttributes> implements AddressAttributes {
...
@@ -104,6 +105,16 @@ class Address extends Model<AddressAttributes> implements AddressAttributes {
public
readonly
updatedAt
!
:
Date
;
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
(
Project
.
init
(
{
{
id
:
{
id
:
{
...
@@ -164,6 +175,32 @@ Address.init(
...
@@ -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.
// Here we associate which actually populates out pre-declared `association` static and other methods.
User
.
hasMany
(
Project
,
{
User
.
hasMany
(
Project
,
{
sourceKey
:
"id"
,
sourceKey
:
"id"
,
...
...
types/lib/model.d.ts
View file @
5cabcbc
...
@@ -2849,6 +2849,8 @@ export type ModelType = typeof Model;
...
@@ -2849,6 +2849,8 @@ export type ModelType = typeof Model;
// must come first for unknown reasons.
// must come first for unknown reasons.
export
type
ModelCtor
<
M
extends
Model
>
=
typeof
Model
&
{
new
():
M
};
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
type
ModelStatic
<
M
extends
Model
>
=
{
new
():
M
};
export
default
Model
;
export
default
Model
;
types/test/typescriptDocs/ModelInit.ts
View file @
5cabcbc
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
import
{
import
{
Sequelize
,
Sequelize
,
Model
,
Model
,
ModelDefined
,
DataTypes
,
DataTypes
,
HasManyGetAssociationsMixin
,
HasManyGetAssociationsMixin
,
HasManyAddAssociationMixin
,
HasManyAddAssociationMixin
,
...
@@ -12,9 +13,9 @@ import {
...
@@ -12,9 +13,9 @@ import {
HasManyCountAssociationsMixin
,
HasManyCountAssociationsMixin
,
HasManyCreateAssociationMixin
,
HasManyCreateAssociationMixin
,
Optional
,
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
// These are all the attributes in the User model
interface
UserAttributes
{
interface
UserAttributes
{
...
@@ -24,7 +25,7 @@ interface UserAttributes {
...
@@ -24,7 +25,7 @@ interface UserAttributes {
}
}
// Some attributes are optional in `User.build` and `User.create` calls
// 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
>
class
User
extends
Model
<
UserAttributes
,
UserCreationAttributes
>
implements
UserAttributes
{
implements
UserAttributes
{
...
@@ -60,7 +61,7 @@ interface ProjectAttributes {
...
@@ -60,7 +61,7 @@ interface ProjectAttributes {
name
:
string
;
name
:
string
;
}
}
interface
ProjectCreationAttributes
extends
Optional
<
ProjectAttributes
,
'id'
>
{}
interface
ProjectCreationAttributes
extends
Optional
<
ProjectAttributes
,
"id"
>
{}
class
Project
extends
Model
<
ProjectAttributes
,
ProjectCreationAttributes
>
class
Project
extends
Model
<
ProjectAttributes
,
ProjectCreationAttributes
>
implements
ProjectAttributes
{
implements
ProjectAttributes
{
...
@@ -87,6 +88,17 @@ class Address extends Model<AddressAttributes> implements AddressAttributes {
...
@@ -87,6 +88,17 @@ class Address extends Model<AddressAttributes> implements AddressAttributes {
public
readonly
updatedAt
!
:
Date
;
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
(
Project
.
init
(
{
{
id
:
{
id
:
{
...
@@ -105,8 +117,8 @@ Project.init(
...
@@ -105,8 +117,8 @@ Project.init(
},
},
{
{
sequelize
,
sequelize
,
tableName
:
'projects'
,
tableName
:
"projects"
,
}
,
}
);
);
User
.
init
(
User
.
init
(
...
@@ -126,9 +138,9 @@ User.init(
...
@@ -126,9 +138,9 @@ User.init(
},
},
},
},
{
{
tableName
:
'users'
,
tableName
:
"users"
,
sequelize
,
// passing the `sequelize` instance is required
sequelize
,
// passing the `sequelize` instance is required
}
,
}
);
);
Address
.
init
(
Address
.
init
(
...
@@ -142,30 +154,56 @@ Address.init(
...
@@ -142,30 +154,56 @@ Address.init(
},
},
},
},
{
{
tableName
:
'address'
,
tableName
:
"address"
,
sequelize
,
// passing the `sequelize` instance is required
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.
// Here we associate which actually populates out pre-declared `association` static and other methods.
User
.
hasMany
(
Project
,
{
User
.
hasMany
(
Project
,
{
sourceKey
:
'id'
,
sourceKey
:
"id"
,
foreignKey
:
'ownerId'
,
foreignKey
:
"ownerId"
,
as
:
'projects'
,
// this determines the name in `associations`!
as
:
"projects"
,
// this determines the name in `associations`!
});
});
Address
.
belongsTo
(
User
,
{
targetKey
:
'id'
});
Address
.
belongsTo
(
User
,
{
targetKey
:
"id"
});
User
.
hasOne
(
Address
,
{
sourceKey
:
'id'
});
User
.
hasOne
(
Address
,
{
sourceKey
:
"id"
});
async
function
doStuffWithUser
()
{
async
function
doStuffWithUser
()
{
const
newUser
=
await
User
.
create
({
const
newUser
=
await
User
.
create
({
name
:
'Johnny'
,
name
:
"Johnny"
,
preferredName
:
'John'
,
preferredName
:
"John"
,
});
});
console
.
log
(
newUser
.
id
,
newUser
.
name
,
newUser
.
preferredName
);
console
.
log
(
newUser
.
id
,
newUser
.
name
,
newUser
.
preferredName
);
const
project
=
await
newUser
.
createProject
({
const
project
=
await
newUser
.
createProject
({
name
:
'first!'
,
name
:
"first!"
,
});
});
const
ourUser
=
await
User
.
findByPk
(
1
,
{
const
ourUser
=
await
User
.
findByPk
(
1
,
{
...
...
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