Skip to content

Support ES6 constructor.name  #37340

Closed
Closed

Description

TypeScript Version: Nightly

Search Terms: 'constuctor name'

Expected behavior:
No errors.

Actual behavior:
See the playground and code links below. Uncomment the notes line and see that typescript produces z Property 'join' does not exist on type 'string'.` for code that only runs on Arrays.

Related Issues:
Nope

Code

function runMe(options: any) {
  const params = {};
  Object.keys(options).forEach(function (option: string | string[]) {
    // Using the ES6 constructor.name per below will trigger incorrect warnings
    // if (option.constructor.name === 'Array') {
    if (Array.isArray(option)) {
      option = option.join(",")
    }
  });
  return params;
}
Output
"use strict";
function runMe(options) {
    const params = {};
    Object.keys(options).forEach(function (option) {
        // Using the ES6 cnstructor.name per below will trigger 
        // if (option.constructor.name === 'Array') {
        if (Array.isArray(option)) {
            option = option.join(",");
        }
    });
    return params;
}
Compiler Options
{
  "compilerOptions": {
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictPropertyInitialization": true,
    "strictBindCallApply": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "useDefineForClassFields": false,
    "alwaysStrict": true,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "downlevelIteration": false,
    "noEmitHelpers": false,
    "noLib": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "esModuleInterop": true,
    "preserveConstEnums": false,
    "removeComments": false,
    "skipLibCheck": false,
    "checkJs": false,
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": false,
    "emitDecoratorMetadata": false,
    "target": "ES2017",
    "module": "ESNext"
  }
}

Playground Link: Provided

Activity

  1. RyanCavanaugh commented on Mar 11, 2020

    @RyanCavanaugh
    Member

    ?
    image

  2. mikemaccana commented on Mar 12, 2020

    @mikemaccana
    Author

    Ryan Cavanaugh (@RyanCavanaugh) you've used two checks for Array in your code above. The intention is you only use one mechanism to check the object is an array (either Array.isArray(object) or checking object.contructor.name) and compare the results.

    image

  3. added
    DeclinedThe issue was declined as something which matches the TypeScript vision
    SuggestionAn idea for TypeScript
    and removed
    Needs More InfoThe issue still hasn't been fully clarified
    on Mar 12, 2020
  4. RyanCavanaugh commented on Mar 12, 2020

    @RyanCavanaugh
    Member

    This isn't a type guard pattern we support, nor do we intend to.

  5. changed the title [-]Using ES6 constructor.name for type checking produces incorrect typescript errors when using union types[/-] [+]Support ES6 constructor.name [/+] on Mar 13, 2020
  6. mikemaccana commented on Mar 13, 2020

    @mikemaccana
    Author

    Why not? constructor.name is part of ES6, and allows users to determine type more easily than knowing each type-specific check. Here's a quote from Domenic Denicola:

    someClassInstance.constructor.name is exactly the correct way to do this. Transpilers may not support this, but it is the standard way per the specification. (The name property of functions declared via ClassDeclaration productions is set in 14.5.15, step 6.)

  7. RyanCavanaugh commented on Mar 13, 2020

    @RyanCavanaugh
    Member

    This kind of check gets it wrong in both directions. You could have a value whose constructor.name property was "Array" that wasn't an array (because there was a class Array declared somewhere else), and you could have a value whose constructor.name wasn't "Array" but was an array (because it's e.g. class MyArray extends Array).

  8. mikemaccana commented on Mar 17, 2020

    @mikemaccana
    Author

    Hi Ryan Cavanaugh (@RyanCavanaugh)! Understood and thanks for the reply. 👍🏽

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DeclinedThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions