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