不要怂,就是干,撸起袖子干!

Commit de5f21dc by KapitanOczywisty Committed by GitHub

fix(types): models with attributes couldn't be used in some cases (#13010)

1 parent 88925077
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
InstanceUpdateOptions, InstanceUpdateOptions,
Model, Model,
ModelCtor, ModelCtor,
ModelType,
Transactionable, Transactionable,
WhereOptions, WhereOptions,
} from '../model'; } from '../model';
...@@ -21,7 +22,7 @@ export interface ThroughOptions { ...@@ -21,7 +22,7 @@ export interface ThroughOptions {
* The model used to join both sides of the N:M association. * The model used to join both sides of the N:M association.
* Can be a string if you want the model to be generated by sequelize. * Can be a string if you want the model to be generated by sequelize.
*/ */
model: typeof Model | string; model: ModelType | string;
/** /**
* If true the generated join table will be paranoid * If true the generated join table will be paranoid
...@@ -59,7 +60,7 @@ export interface BelongsToManyOptions extends ManyToManyOptions { ...@@ -59,7 +60,7 @@ export interface BelongsToManyOptions extends ManyToManyOptions {
* The name of the table that is used to join source and target in n:m associations. Can also be a * The name of the table that is used to join source and target in n:m associations. Can also be a
* sequelize model if you want to define the junction table yourself and add extra attributes to it. * sequelize model if you want to define the junction table yourself and add extra attributes to it.
*/ */
through: typeof Model | string | ThroughOptions; through: ModelType | string | ThroughOptions;
/** /**
* The name of the foreign key in the join table (representing the target model) or an object representing * The name of the foreign key in the join table (representing the target model) or an object representing
......
import { ModelType } from '../index';
import { ValidationOptions } from './instance-validator'; import { ValidationOptions } from './instance-validator';
import Model, { import Model, {
BulkCreateOptions, BulkCreateOptions,
...@@ -65,7 +66,7 @@ export interface SequelizeHooks< ...@@ -65,7 +66,7 @@ export interface SequelizeHooks<
TCreationAttributes = TAttributes TCreationAttributes = TAttributes
> extends ModelHooks<M, TAttributes> { > extends ModelHooks<M, TAttributes> {
beforeDefine(attributes: ModelAttributes<M, TCreationAttributes>, options: ModelOptions<M>): void; beforeDefine(attributes: ModelAttributes<M, TCreationAttributes>, options: ModelOptions<M>): void;
afterDefine(model: typeof Model): void; afterDefine(model: ModelType): void;
beforeInit(config: Config, options: Options): void; beforeInit(config: Config, options: Options): void;
afterInit(sequelize: Sequelize): void; afterInit(sequelize: Sequelize): void;
beforeConnect(config: Config): HookReturn; beforeConnect(config: Config): HookReturn;
......
import { Model } from './model'; import { Model, ModelType } from './model';
import { Sequelize } from './sequelize'; import { Sequelize } from './sequelize';
export class ModelManager { export class ModelManager {
...@@ -7,8 +7,8 @@ export class ModelManager { ...@@ -7,8 +7,8 @@ export class ModelManager {
public all: typeof Model[]; public all: typeof Model[];
constructor(sequelize: Sequelize); constructor(sequelize: Sequelize);
public addModel<T extends typeof Model>(model: T): T; public addModel<T extends ModelType>(model: T): T;
public removeModel(model: typeof Model): void; public removeModel(model: ModelType): void;
public getModel(against: unknown, options?: { attribute?: string }): typeof Model; public getModel(against: unknown, options?: { attribute?: string }): typeof Model;
} }
......
...@@ -379,7 +379,7 @@ export interface IncludeThroughOptions extends Filterable<any>, Projectable { ...@@ -379,7 +379,7 @@ export interface IncludeThroughOptions extends Filterable<any>, Projectable {
/** /**
* Options for eager-loading associated models, also allowing for all associations to be loaded at once * Options for eager-loading associated models, also allowing for all associations to be loaded at once
*/ */
export type Includeable = typeof Model | Association | IncludeOptions | { all: true, nested?: true } | string; export type Includeable = ModelType | Association | IncludeOptions | { all: true, nested?: true } | string;
/** /**
* Complex include options * Complex include options
...@@ -392,7 +392,7 @@ export interface IncludeOptions extends Filterable<any>, Projectable, Paranoid { ...@@ -392,7 +392,7 @@ export interface IncludeOptions extends Filterable<any>, Projectable, Paranoid {
/** /**
* The model you want to eagerly load * The model you want to eagerly load
*/ */
model?: typeof Model; model?: ModelType;
/** /**
* The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` / * The alias of the relation, in case the model you want to eagerly load is aliassed. For `hasOne` /
...@@ -1232,7 +1232,7 @@ export interface ModelAttributeColumnReferencesOptions { ...@@ -1232,7 +1232,7 @@ export interface ModelAttributeColumnReferencesOptions {
/** /**
* If this column references another table, provide it here as a Model, or a string * If this column references another table, provide it here as a Model, or a string
*/ */
model?: string | typeof Model; model?: string | ModelType;
/** /**
* The column of the foreign table that this column references * The column of the foreign table that this column references
...@@ -1660,7 +1660,7 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut ...@@ -1660,7 +1660,7 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut
this: ModelStatic<M>, this: ModelStatic<M>,
schema: string, schema: string,
options?: SchemaOptions options?: SchemaOptions
): { new(): M } & typeof Model; ): ModelCtor<M>;
/** /**
* Get the tablename of the model, taking schema into account. The method will return The name as a string * Get the tablename of the model, taking schema into account. The method will return The name as a string
...@@ -2127,7 +2127,7 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut ...@@ -2127,7 +2127,7 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut
/** /**
* Unscope the model * Unscope the model
*/ */
public static unscoped<M extends typeof Model>(this: M): M; public static unscoped<M extends ModelType>(this: M): M;
/** /**
* A hook that is run before validation * A hook that is run before validation
...@@ -2833,7 +2833,7 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut ...@@ -2833,7 +2833,7 @@ export abstract class Model<TModelAttributes extends {} = any, TCreationAttribut
public isSoftDeleted(): boolean; public isSoftDeleted(): boolean;
} }
export type ModelType = typeof Model; export type ModelType<TModelAttributes = any, TCreationAttributes = TModelAttributes> = new () => Model<TModelAttributes, TCreationAttributes>;
// Do not switch the order of `typeof Model` and `{ new(): M }`. For // Do not switch the order of `typeof Model` and `{ new(): M }`. For
// instances created by `sequelize.define` to typecheck well, `typeof Model` // instances created by `sequelize.define` to typecheck well, `typeof Model`
......
...@@ -8,7 +8,7 @@ import { ...@@ -8,7 +8,7 @@ import {
WhereOptions, WhereOptions,
Filterable, Filterable,
Poolable, Poolable,
ModelCtor, ModelStatic ModelCtor, ModelStatic, ModelType
} from './model'; } from './model';
import QueryTypes = require('./query-types'); import QueryTypes = require('./query-types');
import { Sequelize, RetryOptions } from './sequelize'; import { Sequelize, RetryOptions } from './sequelize';
...@@ -487,7 +487,7 @@ export class QueryInterface { ...@@ -487,7 +487,7 @@ export class QueryInterface {
insertValues: object, insertValues: object,
updateValues: object, updateValues: object,
where: object, where: object,
model: typeof Model, model: ModelType,
options?: QueryOptions options?: QueryOptions
): Promise<object>; ): Promise<object>;
...@@ -540,13 +540,13 @@ export class QueryInterface { ...@@ -540,13 +540,13 @@ export class QueryInterface {
tableName: TableName, tableName: TableName,
identifier: WhereOptions<any>, identifier: WhereOptions<any>,
options?: QueryOptions, options?: QueryOptions,
model?: typeof Model model?: ModelType
): Promise<object>; ): Promise<object>;
/** /**
* Returns selected rows * Returns selected rows
*/ */
public select(model: typeof Model | null, tableName: TableName, options?: QueryOptionsWithWhere): Promise<object[]>; public select(model: ModelType | null, tableName: TableName, options?: QueryOptionsWithWhere): Promise<object[]>;
/** /**
* Increments a row value * Increments a row value
...@@ -566,7 +566,7 @@ export class QueryInterface { ...@@ -566,7 +566,7 @@ export class QueryInterface {
tableName: TableName, tableName: TableName,
options: QueryOptionsWithWhere, options: QueryOptionsWithWhere,
attributeSelector: string | string[], attributeSelector: string | string[],
model?: typeof Model model?: ModelType
): Promise<string[]>; ): Promise<string[]>;
/** /**
......
...@@ -20,6 +20,7 @@ import { ...@@ -20,6 +20,7 @@ import {
WhereOperators, WhereOperators,
ModelCtor, ModelCtor,
Hookable, Hookable,
ModelType,
} from './model'; } from './model';
import { ModelManager } from './model-manager'; import { ModelManager } from './model-manager';
import { QueryInterface, QueryOptions, QueryOptionsWithModel, QueryOptionsWithType, ColumnsDescription } from './query-interface'; import { QueryInterface, QueryOptions, QueryOptionsWithModel, QueryOptionsWithType, ColumnsDescription } from './query-interface';
...@@ -747,8 +748,8 @@ export class Sequelize extends Hooks { ...@@ -747,8 +748,8 @@ export class Sequelize extends Hooks {
* @param name * @param name
* @param fn A callback function that is called with factory * @param fn A callback function that is called with factory
*/ */
public static afterDefine(name: string, fn: (model: typeof Model) => void): void; public static afterDefine(name: string, fn: (model: ModelType) => void): void;
public static afterDefine(fn: (model: typeof Model) => void): void; public static afterDefine(fn: (model: ModelType) => void): void;
/** /**
* A hook that is run before Sequelize() call * A hook that is run before Sequelize() call
...@@ -1046,8 +1047,8 @@ export class Sequelize extends Hooks { ...@@ -1046,8 +1047,8 @@ export class Sequelize extends Hooks {
* @param name * @param name
* @param fn A callback function that is called with factory * @param fn A callback function that is called with factory
*/ */
public afterDefine(name: string, fn: (model: typeof Model) => void): void; public afterDefine(name: string, fn: (model: ModelType) => void): void;
public afterDefine(fn: (model: typeof Model) => void): void; public afterDefine(fn: (model: ModelType) => void): void;
/** /**
* A hook that is run before Sequelize() call * A hook that is run before Sequelize() call
......
import { DataType } from './data-types'; import { DataType } from './data-types';
import { Model, ModelCtor, WhereOptions } from './model'; import { Model, ModelCtor, ModelType, WhereOptions } from './model';
export type Primitive = 'string' | 'number' | 'boolean'; export type Primitive = 'string' | 'number' | 'boolean';
...@@ -40,9 +40,9 @@ export function mapOptionFieldNames<M extends Model, T extends OptionsForMapping ...@@ -40,9 +40,9 @@ export function mapOptionFieldNames<M extends Model, T extends OptionsForMapping
options: T, model: ModelCtor<M> options: T, model: ModelCtor<M>
): T; ): T;
export function mapWhereFieldNames(attributes: object, model: typeof Model): object; export function mapWhereFieldNames(attributes: object, model: ModelType): object;
/** Used to map field names in values */ /** Used to map field names in values */
export function mapValueFieldNames(dataValues: object, fields: string[], model: typeof Model): object; export function mapValueFieldNames(dataValues: object, fields: string[], model: ModelType): object;
export function isColString(value: string): boolean; export function isColString(value: string): boolean;
export function canTreatArrayAsAnd(arr: unknown[]): boolean; export function canTreatArrayAsAnd(arr: unknown[]): boolean;
......
import { Model } from "sequelize/lib/model";
interface UserCreationAttributes {
name: string;
}
interface UserAttributes extends UserCreationAttributes {
id: number;
}
class User
extends Model<UserAttributes, UserCreationAttributes>
implements UserAttributes {
public id!: number;
public name!: string;
public readonly projects?: Project[];
public readonly address?: Address;
}
interface ProjectCreationAttributes {
ownerId: number;
name: string;
}
interface ProjectAttributes extends ProjectCreationAttributes {
id: number;
}
class Project
extends Model<ProjectAttributes, ProjectCreationAttributes>
implements ProjectAttributes {
public id!: number;
public ownerId!: number;
public name!: string;
}
class Address extends Model {
public userId!: number;
public address!: string;
}
// both models should be accepted in include
User.findAll({ include: [Project, Address] });
...@@ -193,7 +193,9 @@ async function test() { ...@@ -193,7 +193,9 @@ async function test() {
}, },
}); });
await queryInterface.upsert("test", {"a": 1}, {"b": 2}, {"c": 3}, Model, {}); class TestModel extends Model {}
await queryInterface.upsert("test", {"a": 1}, {"b": 2}, {"c": 3}, TestModel, {});
await queryInterface.insert(null, 'test', {}); await queryInterface.insert(null, 'test', {});
} }
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!