question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TS is overly picky when declaring a class constructor type

See original GitHub issue

TypeScript Version: 3.4.0-dev.20190202

Search Terms: class, extend, constructor, any[]

Code

type ClassConstructor = new(...args: any[]) => {}

function mixin<C extends ClassConstructor>(Class: C) {
  return class extends Class {}
}

Expected behavior:

I should be able to replace ...args: any[] with ...args: unknown[], or any other signature.

Actual behavior:

Error: Type 'C' is not a constructor function type. [2507]

Playground Link: https://www.typescriptlang.org/play/index.html#src=type ClassConstructor %3D new(...args%3A unknown[]) %3D> {} function mixin<C extends ClassConstructor>(Class%3A C) { return class extends Class {} }

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:5
  • Comments:8 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
RyanCavanaughcommented, Feb 4, 2019

Agree, unknown[] should be an acceptable substitute. Accepting PRs for an easy fix.

1reaction
dragomirtitiancommented, Feb 5, 2019

@RyanCavanaugh I can look into that, but this problem seems much bigger than mixins and would have implications broadly. Rest parameters of type unknown[] are generally not compatible with arbitrary parameter types even if we are talking about a constraint. This currently fails under strictFunctionTypes


function test<T extends (...a: unknown[]) => unknown>(fn:T) : T{
      fn(""); // this passes "" can be assigned to unknown 
      return fn;
}
test(function (a: number) {   // error here under strictFunctionTypes
})

I’m not 100% sure it is necessarily a great idea to make the code above error free . It seems to be weaker as far as type safety goes. As we see in the code above the callback passed in accepts a number but it’s called inside test with a string. I think the current behavior is better, don’t let a function with a number parameter be assigned to a function with an unknown parameter, the implementing function can’t handle unknown.

While this is no worse than if we use any[], unknown[] would give a false sense of type-safety when no safety actually exists. Except for obeying the no-any tslint rule not sure why unknown is better in this instance. At least any would function as a ‘💀💀 careful unsafe 💀💀’ warning, at least that’s the way I see any 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Class constructor type in typescript? - Stack Overflow
typeof Class is the type of the class constructor. It's preferable to the custom constructor type declaration because it processes static class ...
Read more >
Documentation - Classes - TypeScript
Class constructors are very similar to functions. ... Constructors can't have type parameters - these belong on the outer class declaration, ...
Read more >
Writing a constructor in TypeScript - LogRocket Blog
This reads weirdly, but it essentially means that the constructor isn't an instance type method. By instance type method, we're referring to a ......
Read more >
Classes | Kotlin Documentation
The class declaration consists of the class name, the class header (specifying its type parameters, the primary constructor, and some other things), and...
Read more >
TypeScript Basics 13 - Methods and constructors - YouTube
Access the full course here: https://javabrains.io/courses/typescript_basics Learn how to define methods in a TypeScript class.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found