Skip to content

[4.2.2] Compiler crash with null pointer in tsc.js: isWeakType resolved.callSignatures is null #42942

@paztis

Description

@paztis

Bug Report

🔎 Search Terms

resolved.callSignatures

🕗 Version & Regression Information

  • This is a crash
  • This changed between versions 4.1.0 and 4.2.2

⏯ Playground Link

Playground link with relevant code

💻 Code

// We can quickly address your report if:
//  - The code sample is short. Nearly all TypeScript bugs can be demonstrated in 20-30 lines of code!
//  - It doesn't use external libraries. These are often issues with the type definitions rather than TypeScript bugs.
//  - The incorrectness of the behavior is readily apparent from reading the sample.
// Reports are slower to investigate if:
//  - We have to pare too much extraneous code.
//  - We have to clone a large repo and validate that the problem isn't elsewhere.
//  - The sample is confusing or doesn't clearly demonstrate what's wrong.

source code:

function isWeakType(type) {
    if (type.flags & 524288) {
        var resolved = resolveStructuredTypeMembers(type);
        return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 &&
            !resolved.stringIndexInfo && !resolved.numberIndexInfo &&
            resolved.properties.length > 0 &&
            ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216); });
    }
    if (type.flags & 2097152) {
        return ts.every(type.types, isWeakType);
    }
    return false;
}

error log:

TypeError: Cannot read property 'length' of undefined
    at isWeakType (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:50733:48)
    at isRelatedTo (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:49252:58)
    at checkTypeRelatedTo (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:48974:26)
    at isTypeRelatedTo (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:48938:24)
    at removeSubtypes (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:46041:33)
    at getUnionType (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:46131:26)
    at getWidenedTypeForAssignmentDeclaration (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:42011:28)
    at getTypeOfFuncClassEnumModuleWorker (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:42497:34)
    at getTypeOfFuncClassEnumModule (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:42476:51)
    at getTypeOfSymbol (/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/typescript/lib/tsc.js:42579:24)

value of the resolved variable at crash time:

Type {
  flags: 524288,
  id: 5978,
  objectFlags: 16,
  symbol: <ref *1> Symbol {
    flags: 33554960,
    escapedName: '_extends',
    declarations: [ [Node] ],
    valueDeclaration: Node {
      pos: 0,
      end: 479,
      kind: 251,
      id: 5476,
      flags: 131072,
      modifierFlagsCache: 536870912,
      transformFlags: 1052704,
      parent: [Node],
      original: undefined,
      decorators: undefined,
      modifiers: undefined,
      symbol: [Symbol],
      localSymbol: undefined,
      locals: Map(0) {},
      nextContainer: [Node],
      name: [Identifier],
      typeParameters: undefined,
      parameters: [Array],
      type: undefined,
      body: [Node],
      asteriskToken: undefined,
      returnFlowNode: [Object],
      jsDocCache: []
    },
    id: undefined,
    mergeId: undefined,
    parent: undefined,
    checkFlags: 0,
    exports: Map(2) { 'default' => [Symbol], '___esModule' => [Symbol] },
    cjsExportMerged: [Circular *1],
    type: Type {
      flags: 524288,
      id: 5976,
      objectFlags: 16,
      symbol: [Circular *1],
      members: [Map],
      properties: undefined,
      callSignatures: undefined,
      constructSignatures: undefined,
      stringIndexInfo: undefined,
      numberIndexInfo: undefined
    },
    resolvedExports: Map(2) { 'default' => [Symbol], '___esModule' => [Symbol] }
  },
  members: Map(2) {
    'default' => Symbol {
      flags: 2097152,
      escapedName: 'default',
      declarations: [Array],
      valueDeclaration: undefined,
      id: 6422,
      mergeId: undefined,
      parent: [Symbol]
    },
    '___esModule' => Symbol {
      flags: 1048580,
      escapedName: '___esModule',
      declarations: [Array],
      valueDeclaration: [Node],
      id: undefined,
      mergeId: undefined,
      parent: [Symbol]
    }
  },
  properties: [
    Symbol {
      flags: 2097152,
      escapedName: 'default',
      declarations: [Array],
      valueDeclaration: undefined,
      id: 6422,
      mergeId: undefined,
      parent: [Symbol]
    },
    Symbol {
      flags: 1048580,
      escapedName: '___esModule',
      declarations: [Array],
      valueDeclaration: [Node],
      id: undefined,
      mergeId: undefined,
      parent: [Symbol]
    }
  ],
  callSignatures: undefined,
  constructSignatures: undefined,
  stringIndexInfo: undefined,
  numberIndexInfo: undefined
}

value of resolved.symbol.declarations[0]:
seems to came from @babel/runtime (in v7.13.7 on my node_modules)

<ref *1> Node {
  pos: 0,
  end: 479,
  kind: 251,
  id: 5476,
  flags: 131072,
  modifierFlagsCache: 536870912,
  transformFlags: 1052704,
  parent: <ref *2> Node {
    pos: 0,
    end: 586,
    kind: 297,
    id: 5471,
    flags: 131072,
    modifierFlagsCache: 536870912,
    transformFlags: 32,
    parent: undefined,
    original: undefined,
    statements: [
      [Circular *1],
      [Node],
      [Node],
      pos: 0,
      end: 585,
      hasTrailingComma: false,
      transformFlags: 32
    ],
    endOfFileToken: Token {
      pos: 585,
      end: 586,
      kind: 1,
      id: 0,
      flags: 131072,
      transformFlags: 0,
      parent: [Circular *2]
    },
    fileName: '/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/@babel/runtime/helpers/extends/index.js',
    text: 'function _extends() {\n' +
      '  module.exports = _extends = Object.assign || function (target) {\n' +
      '    for (var i = 1; i < arguments.length; i++) {\n' +
      '      var source = arguments[i];\n' +
      '\n' +
      '      for (var key in source) {\n' +
      '        if (Object.prototype.hasOwnProperty.call(source, key)) {\n' +
      '          target[key] = source[key];\n' +
      '        }\n' +
      '      }\n' +
      '    }\n' +
      '\n' +
      '    return target;\n' +
      '  };\n' +
      '\n' +
      '  module.exports["default"] = module.exports, module.exports.__esModule = true;\n' +
      '  return _extends.apply(this, arguments);\n' +
      '}\n' +
      '\n' +
      'module.exports = _extends;\n' +
      'module.exports["default"] = module.exports, module.exports.__esModule = true;\n',
    languageVersion: 99,
    languageVariant: 1,
    scriptKind: 1,
    isDeclarationFile: false,
    hasNoDefaultLib: false,
    externalModuleIndicator: undefined,
    bindDiagnostics: [],
    bindSuggestionDiagnostics: undefined,
    pragmas: Map(0) {},
    checkJsDirective: undefined,
    referencedFiles: [],
    typeReferenceDirectives: [],
    libReferenceDirectives: [],
    amdDependencies: [],
    commentDirectives: undefined,
    nodeCount: 129,
    identifierCount: 48,
    identifiers: Map(17) {
      '_extends' => '_extends',
      'module' => 'module',
      'exports' => 'exports',
      'Object' => 'Object',
      'assign' => 'assign',
      'target' => 'target',
      'i' => 'i',
      'arguments' => 'arguments',
      'length' => 'length',
      'source' => 'source',
      'key' => 'key',
      'prototype' => 'prototype',
      'hasOwnProperty' => 'hasOwnProperty',
      'call' => 'call',
      'default' => 'default',
      '__esModule' => '__esModule',
      'apply' => 'apply'
    },
    parseDiagnostics: [],
    path: '/users/jeromeh/workspaces/experience-core/digitalexp-ui-base/node_modules/@babel/runtime/helpers/extends/index.js',
    resolvedPath: '/users/jeromeh/workspaces/experience-core/digitalexp-ui-base/node_modules/@babel/runtime/helpers/extends/index.js',
    originalFileName: '/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/@babel/runtime/helpers/extends/index.js',
    imports: [],
    moduleAugmentations: [],
    ambientModuleNames: [],
    resolvedModules: undefined,
    additionalSyntacticDiagnostics: [],
    locals: Map(2) { '_extends' => [Symbol], 'module' => [Symbol] },
    nextContainer: [Circular *1],
    commonJsModuleIndicator: Node {
      pos: 21,
      end: 353,
      kind: 216,
      id: 0,
      flags: 131072,
      modifierFlagsCache: 536870912,
      transformFlags: 32,
      parent: [Node],
      original: undefined,
      left: [Node],
      operatorToken: [Token],
      right: [Node],
      symbol: [Symbol]
    },
    symbol: Symbol {
      flags: 512,
      escapedName: '"/Users/jeromeh/Workspaces/experience-core/digitalexp-ui-base/node_modules/@babel/runtime/helpers/extends/index"',
      declarations: [Array],
      valueDeclaration: [Circular *2],
      id: undefined,
      mergeId: undefined,
      parent: undefined,
      exports: [Map]
    },
    symbolCount: 12,
    classifiableNames: Set(2) { 'export=', 'default' },
    jsDocCache: []
  },
  original: undefined,
  decorators: undefined,
  modifiers: undefined,
  symbol: Symbol {
    flags: 16,
    escapedName: '_extends',
    declarations: [ [Circular *1] ],
    valueDeclaration: [Circular *1],
    id: 6415,
    mergeId: 1689,
    parent: undefined,
    isReferenced: 1949695
  },
  localSymbol: undefined,
  locals: Map(0) {},
  nextContainer: <ref *3> Node {
    pos: 68,
    end: 353,
    kind: 208,
    id: 5472,
    flags: 131072,
    modifierFlagsCache: 536875008,
    transformFlags: 1048608,
    parent: Node {
      pos: 51,
      end: 353,
      kind: 216,
      id: 0,
      flags: 131072,
      modifierFlagsCache: 0,
      transformFlags: 32,
      parent: [Node],
      original: undefined,
      left: [Node],
      operatorToken: [Token],
      right: [Circular *3]
    },
    original: undefined,
    decorators: undefined,
    modifiers: undefined,
    symbol: Symbol {
      flags: 16,
      escapedName: '__function',
      declarations: [Array],
      valueDeclaration: [Circular *3],
      id: 6416,
      mergeId: undefined,
      parent: undefined
    },
    localSymbol: undefined,
    locals: Map(4) {
      'target' => [Symbol],
      'i' => [Symbol],
      'source' => [Symbol],
      'key' => [Symbol]
    },
    nextContainer: undefined,
    name: undefined,
    typeParameters: undefined,
    parameters: [
      [Node],
      pos: 79,
      end: 85,
      hasTrailingComma: false,
      transformFlags: 0
    ],
    type: undefined,
    body: Node {
      pos: 86,
      end: 353,
      kind: 230,
      id: 0,
      flags: 131072,
      modifierFlagsCache: 0,
      transformFlags: 1048608,
      parent: [Circular *3],
      original: undefined,
      statements: [Array],
      multiLine: true
    },
    asteriskToken: undefined,
    flowNode: { flags: 6208, antecedent: [Object], node: [Node] },
    returnFlowNode: { flags: 6152, antecedents: [Array], id: 81 },
    jsDocCache: []
  },
  name: Identifier {
    pos: 8,
    end: 17,
    kind: 78,
    id: 0,
    flags: 131072,
    transformFlags: 0,
    parent: [Circular *1],
    original: undefined,
    flowNode: { flags: 6146 },
    originalKeywordKind: undefined,
    escapedText: '_extends'
  },
  typeParameters: undefined,
  parameters: [ pos: 18, end: 18, hasTrailingComma: false, transformFlags: 0 ],
  type: undefined,
  body: Node {
    pos: 19,
    end: 479,
    kind: 230,
    id: 0,
    flags: 131072,
    modifierFlagsCache: 0,
    transformFlags: 1052704,
    parent: [Circular *1],
    original: undefined,
    statements: [
      [Node],
      [Node],
      [Node],
      pos: 21,
      end: 477,
      hasTrailingComma: false,
      transformFlags: 1052704
    ],
    multiLine: true
  },
  asteriskToken: undefined,
  returnFlowNode: {
    flags: 2064,
    antecedent: { flags: 2304, antecedent: [Object], node: [Node] },
    node: Node {
      pos: 401,
      end: 427,
      kind: 201,
      id: 0,
      flags: 131072,
      modifierFlagsCache: 536870912,
      transformFlags: 0,
      parent: [Node],
      original: undefined,
      expression: [Node],
      name: [Identifier],
      symbol: [Symbol],
      flowNode: [Object]
    }
  },
  jsDocCache: []
}

🙁 Actual behavior

Crash

🙂 Expected behavior

Don't crash

Metadata

Metadata

Assignees

Labels

Needs More InfoThe issue still hasn't been fully clarified

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions