Skip to content

@record types with no members have no create() method #51

@niloc132

Description

@niloc132

Steps to reproduce, create a record type with no members.

/**
 * @record
 */
function MyRecord() {}

Expected, a Java interface with a static create() method. Actual output is a Java interface with no contents.

--

While this might seem like a weird edge case, there are at least two ways that this comes up. First, when tsickle generates externs from typescript where a type is re-exported in another file, tsickle will generate a new type that extends the existing type. Second, a record type that extends from two other record types, but doesn't contribute new fields.

/**
 * @record
 */
function ParentRecordA() {}

/**
 * @type {string}
 */
ParentRecordA.prototype.name;

/**
 * @record
 */
function ParentRecordB() {}

/**
 * @type {number}
 */
ParentRecordB.prototype.value;

/**
 * @record
 * @extends {ParentRecordA}
 * @extends {ParentRecordB}
 */
function ChildRecord() {}

Expected Java output,

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public interface ChildRecord extends ParentRecordA, ParentRecordB {
  @JsOverlay
  static ChildRecord create() {
    return Js.uncheckedCast(JsPropertyMap.of());
  }
}

Actual Java output

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public interface ChildRecord extends ParentRecordA, ParentRecordB { }

An easy workaround is to just create an instance of a supertype, or just a plain JsObject.create(null) or JsPropertyMap.of(), then wrap in a cast as the usual implementation does. But this isn't expected to be the correct way, since all other records get a generated factory method.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions