Sequelize / Typescript: Types of parameters 'values' and 'values' are incompatible - javascript

I'm trying to create a BaseModel from which all my models are inherited.
I'm also trying to create a separate method() function that can get any of my models as argument.
This is my example code:
import {
Model, Optional
} from 'sequelize'; // v6.3.5
interface DefaultAttributes {
id: number;
}
interface TestAttributes extends DefaultAttributes {
field: number;
}
class BaseModel<T extends DefaultAttributes> extends Model<T, Optional<T, 'id'>> {
static test() {
}
}
class MyModel extends BaseModel<TestAttributes> {
}
function method<T extends typeof BaseModel>(model: T) {
model.test();
}
method(MyModel) // <<<<<< TypeScript ERROR
I've tried to do everything just as the documentation described. https://sequelize.org/master/manual/typescript.html
I'm getting the following TypeScript error:
TS2345: Argument of type 'typeof MyModel' is not assignable to parameter of type 'typeof BaseModel'.   Types of parameters 'values' and 'values' are incompatible.     Type 'Optional<T, "id">' is not assignable to type 'Optional<TestAttributes, "id">'.       Property 'field' is missing in type 'Optional<T, "id">' but required in type 'Pick<TestAttributes, "field">'.
Can pls someone help me what did I do wrong, or how can I create a method that can receive any UniqueModel inherited from BaseModel?

Try this:
import {
Model, Optional
} from 'sequelize'; // v6.3.5
interface DefaultAttributes {
id: number;
}
interface TestAttributes extends DefaultAttributes {
field: number;
}
class BaseModel<T extends DefaultAttributes> extends Model<T, Optional<T, 'id'>> {
static test() {
}
}
class MyModel extends BaseModel<TestAttributes> {
}
function method<T extends BaseModel>(model: T) {
model.test();
}
method(MyModel)

Related

error TS2740 Type 'DeepPartial<Quiz>[]' is missing the following properties from type 'Question': id, question, hasId, save, and 4 more

I don't know how to fix this error. Does anyone know what I need to fix to get this code to work?
import { Injectable } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { CreateQuestionDto } from './dto/create-question.dto';
import { Question } from './question.entity';
import { QuestionRepository } from './question.repository';
#Injectable()
export class QuestionService {
constructor(
#InjectRepository(QuestionRepository)
private questionRepository: QuestionRepository,
) {}
async createQuestion(question: CreateQuestionDto): Promise<Question> {
return await this.questionRepository.save(question);
}
}
Returns the following error:
src/modules/quiz/question.service.ts:15:5 - error TS2740: Type 'DeepPartial[]' is missing the following properties from type 'Question': id, question, hasId, save, and 4 more.
15 return await this.questionRepository.save(question);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/modules/quiz/question.service.ts:15:47 - error TS2769: No overload matches this call.
Overload 1 of 4, '(entities: DeepPartial[], options?: SaveOptions): Promise<(DeepPartial & Quiz)[]>', gave the following error.
Argument of type 'CreateQuestionDto' is not assignable to parameter of type 'DeepPartial[]'.
Type 'CreateQuestionDto' is missing the following properties from type 'DeepPartial[]': length, pop, push, concat, and 29 more.
Overload 2 of 4, '(entity: DeepPartial, options?: SaveOptions): Promise<DeepPartial & Quiz>', gave the following error.
Type 'CreateQuestionDto' has no properties in common with type 'DeepPartial'.
15 return await this.questionRepository.save(question);
Question entity:
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
#Entity('questions')
export class Question extends BaseEntity {
#PrimaryGeneratedColumn()
id: string;
#Column({
type: 'varchar',
})
question: string;
}
Question repository:
import { EntityRepository, Repository } from 'typeorm';
import { Quiz } from './quiz.entity';
#EntityRepository(Quiz)
export class QuestionRepository extends Repository<Quiz> {}
CreateQuestion dto:
import { IsNotEmpty, Length } from 'class-validator';
export class CreateQuestionDto {
#IsNotEmpty()
#Length(3, 255)
question: string;
}
Question repository:
import { EntityRepository, Repository } from 'typeorm';
import { Quiz } from './quiz.entity';
#EntityRepository(Quiz)
export class QuestionRepository extends Repository<Quiz> {}
The problem is that your QuestionRepository is pointing to another entity (Quiz).
Change it to:
export class QuestionRepository extends Repository<Question> {}
That way you can avoid the any clause and use the dto directly on the save call.
async createQuestion(question: CreateQuestionDto): Promise<Question> {
return await this.questionRepository.save(question);
}

Typescript optional parameters overload

I have a class e.g.
class SomeClass {
someMethod(param1: string; param2?: string) { ... }
}
And another one that extends from fore
class AnotherClass extends SomeClass {
someMethod(param1: string) { ... }
}
Also I've got a third class that uses instance of one of these classes as generic e.g.
class ThirdClass<T extends SomeClass> {
instanceClass: T;
}
So I'm getting an error that someMethod in AnotherClass is not compatible with SomeClass, to solve the problem I should make an overload for someMethod in SomeClass :
someMethod(param1: string); // <-- overload
someMethod(param1: string; param2?: string) { ... }
Is there any other way to say TS that everything is ok?

How to call classes and function in type definition file?

I'm newbe in typescript and trying to use type definition file with typescript 2.2, (I'm using typescriptlang.org but can't get answer)I have the following type definition file
export as namespace mydefinition;
export namespace mynamespace {
interface Myinterface {
width: number;
height: number;
}
class MyClass {
constructor(attributes?: any);
addCell(cell: Cell): this;
}
}
I'm using the following line to import file and it success
import { mydefinition } from 'definitionfile';
How can I call the classes and function of this definition file?
Looks good to me. You are just missing the initialization of your myclass.
import { mydefinition } from './definitionfile';
export class classA implements mydefinition.Myinterface {
width: number;
height: number;
constructor() {
var test = new mydefinition.MyClass();
test.addCell("attr");
}
}

Import module to namespace class

I need to import external library to namespace class
app.ts:
namespace GlobNS {
class A {}
}
mod.ts:
import VSTS = require('ExtLib');
namespace GlobNS {
class B extends ExtLib.ISMTH{
prop1: string;
prop2: number;
}
}
ext-lib.d.ts:
declare module ExtLib {
interface ISMTH {
prop1: string;
prop2: number;
}
}
But compiler says: 'Property 'ISMTH' does not exist on type 'typeof 'ExtLib''
Also, why it does not works?
Typescript Playground
Seems you misplaced implements with extends keyword. Try to change your code to:
class B implements ExtLib.ISMTH {
prop1: string;
prop2: number;
}
It should work.

Cannot set property of Interface in TypeScript

I have create a simple interface
module Modules.Part
{
export interface IPart
{
PartId: number;
partNumber: string;
description: string;
}
}
then i have declare this interface in another interface
module Interfaces.Scopes {
export interface IPartScope extends ng.IScope {
part: Modules.Part.IPart;
vm: Controllers.PartCtrl;
}
}
i have use this interface in my class
module Controllers
{
export class PartCtrl
{
constructor(public scope:Interfaces.Scopes.IPartScope)
{
scope.part.PartId = 1;
scope.part.partNumber = "123part";
scope.part.description = "description";
}
}
}
when i am going to set property of IPart interface in my class it's give me following error
TypeError: Cannot set property 'PartId' of undefined
please let me know how to solve this
I'd say, you first need to initialize the part property of the PartCtrl.scope property (which you implicitly defining through the constructor):
constructor(public scope:Interfaces.Scopes.IPartScope)
{
scope.part = [initializer];
scope.part.PartId = 1;
scope.part.partNumber = "123part";
scope.part.description = "description";
}
Since the scope.part is of interface type IPart, you can't create an instance of it but rather have to resolve it somehow. For example:
export interface IActivator<T> {
new (): T;
}
export class PartCtrl<TPart extends IPart>
{
constructor(public scope:Interfaces.Scopes.IPartScope,
activator: IActivator<TPart>)
{
scope.part = new activator();
// ...
}
}
Now you can use the PartCtrl<TPart> in the following way:
export class ConcretePart implements IPart
{
public PartId: number;
public partNumber: string;
public description: string;
}
var ctrl = new PartCtrl(ConcretePart);
Hope this helps.
You can initialize the property "part" with an anonymous object.
scope.part =
{
PartId = 1;
partNumber = "123part";
description = "description";
}
Of course you can also define a class that implements IPart and instantiate it.

Categories

Resources