镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

mixin properties not checked #26286

Closed
Closed

Description

TypeScript Version: master (as of #26283)

Code

/**
 * @template {new (...args: any[]) => any} T
 * @param {T} SuperClass
 */
function myMixin(SuperClass) {
    return class extends SuperClass {
        method() { return 0; }
    }
};

class Base {}
const Mixed = myMixin(Base);

const instance = new Mixed();
instance.method(); // Correctly typed in signature help
instance.meshod(); // But not checked

Run with allowJs, checkJs, and strict.

Expected behavior:

Error at meshod.

Actual behavior:

No error.

Activity

  1. ghost added
    BugA bug in TypeScript
    on Aug 7, 2018
  2. ghost added on Aug 7, 2018
  3. ghost added
    Domain: JSDocRelates to JSDoc parsing and type generation
    on Aug 7, 2018
  4. ghost added
    checkJsRelates to checking JavaScript using TypeScript
    on Aug 7, 2018
  5. ghost added
    Domain: JavaScriptThe issue relates to JavaScript specifically
    on Aug 7, 2018
  6. sandersn commented on Aug 10, 2018

    @sandersn
    Member

    This is true of Typescript as well:

    function mix<T extends new (...args: any[]) => any>(S: T) {
        return class extends S {
            f() { return 0; }
        }
    };
    
    class Base {}
    const Mixed = mix(Base);
    
    export const m = new Mixed();
    m.f(); // Correctly typed in signature help
    m.j(); // should error here, but doesn't
  7. changed the title [-]JavaScript mixin properties not checked[/-] [+]mixin properties not checked[/+] on Aug 10, 2018
  8. sandersn commented on Aug 13, 2018

    @sandersn
    Member

    Well, the reason that you see the apparent type of T is that the any comes from class extends S. S has type T, whose apparent type has a constructor with return type any, which is equivalent to extending any. That’s what allows you to access any property on m.

  9. michaeljota commented on Sep 11, 2018

    @michaeljota

    I though about using InstanceType in the return, that actually makes sense, although the code does throw when expected, it also throws extending S

    function mix<T extends new (...args: any[]) => InstanceType<T>>(S: T) {
        return class extends S { // Throws: Base constructor return type 'InstanceType<T>' is not a class or interface type.
            f() { return 0; }
        }
    };
    
    class Base {}
    const Mixed = mix(Base);
    
    export const m = new Mixed();
    m.f(); // Correctly typed in signature help
    m.j(); // Throws: Property 'j' does not exist on type 'mix<typeof Base>.(Anonymous class) & Base'.

    Maybe I'm using InstanceType poorly, but I think this should be the way to go.

  10. locked as resolved and limited conversation to collaborators on Oct 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptWorking as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions