Repository navigation
Support ES6 constructor.name #37340
Copy link
Copy link
Closed
Labels
DeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptAn idea for TypeScript
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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
DeclinedThe issue was declined as something which matches the TypeScript visionThe issue was declined as something which matches the TypeScript visionSuggestionAn idea for TypeScriptAn idea for TypeScript
Activity
RyanCavanaugh commentedon Mar 11, 2020
?

mikemaccana commentedon Mar 12, 2020
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 checkingobject.contructor.name) and compare the results.RyanCavanaugh commentedon Mar 12, 2020
This isn't a type guard pattern we support, nor do we intend to.
[-]Using ES6 constructor.name for type checking produces incorrect typescript errors when using union types[/-][+]Support ES6 constructor.name [/+]mikemaccana commentedon Mar 13, 2020
Why not?
constructor.nameis part of ES6, and allows users to determine type more easily than knowing each type-specific check. Here's a quote from Domenic Denicola:RyanCavanaugh commentedon Mar 13, 2020
This kind of check gets it wrong in both directions. You could have a value whose
constructor.nameproperty was"Array"that wasn't an array (because there was aclass Arraydeclared somewhere else), and you could have a value whoseconstructor.namewasn't"Array"but was an array (because it's e.g.class MyArray extends Array).mikemaccana commentedon Mar 17, 2020
Hi Ryan Cavanaugh (@RyanCavanaugh)! Understood and thanks for the reply. 👍🏽