Skip to content

RFC: Marking events using @eventClass and/or @eventProperty #30

Open
@octogonz

Description

@octogonz

We have two different API Extractor consumers who define class "events". In C# this is formalized via an event keyword. Although the TypeScript language doesn't model events, it's fairly easy to simulate.

You define an "event class" (e.g. SPEvent) that allows adding/removing handlers:

class FrameworkEvent<TEventArgs extends FrameworkEventArgs> {
  public add(eventHandler: (eventArgs: TEventArgs) => void): void {
     // ...
  }
  public remove(eventHandler: (eventArgs: TEventArgs) => void): void {
     // ...
  }
}

And then you expose readonly-properties (e.g. ApplicationAccessor.navigatedEvent) returning this object:

class MyClass {
  public readonly navigatedEvent: FrameworkEvent<NavigatedEventArgs>;
}

And then users can attach an event handler like this:

const myClass = new MyClass();
myClass.navigatedEvent.add((eventArgs: NavigatedEventArgs) => {
  console.log('Navigated to:' + eventArgs.destinationUrl);
});

The feature request is for the documentation tool to group members like navigatedEvent under an "Events" heading, instead of the usual "Properties" headings.

Proposed Solutions

We're proposing three approaches to support this:

1. Mark up the class: Define a TSDoc tag @eventClass for the class:

/**
 * This is the class used to represent API events.
 * @eventClass
 */
class FrameworkEvent<TEventArgs extends FrameworkEventArgs> {
  public add(eventHandler: (eventArgs: TEventArgs) => void): void {
     // ...
  }
  public remove(eventHandler: (eventArgs: TEventArgs) => void): void {
     // ...
  }
}

Based on this, ideally a tool like API Extractor would recognize any readonly property that returns FrameworkEvent, and automatically classify that as an “event” in the documentation.

2. Mark up each event property: Define a TSDoc tag @eventProperty which needs to be applied to each individual property. This more work for API owners, but it has the benefit of being more obvious to API users who will see these comments in the *.d.ts files. Also it can handle edge cases where something has a signature that looks like an event, but wasn't intended to be. Example:

class MyClass {
  /**
    * This event is fired whenever the application navigates to a new page.
    * @eventProperty 
    */
  public readonly navigatedEvent: FrameworkEvent<NavigatedEventArgs>;
}

3. Both: If we supported both tags, then you would manually mark individual properties as in #2, but a tool like API Extractor can use the information from #1 to find places where @eventProperty is missing or improperly added, and issue appropriate warnings in "strict mode".

NOTE: JSDoc already defines an @event tag with different meaning, so the proposed tags were chosen to avoid conflicts/confusion.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions