[Feature Request] Add generic type parameters to ChangelogFunctions for better type safety · Issue #1722 · changesets/changesets · GitHub
Skip to content

[Feature Request] Add generic type parameters to ChangelogFunctions for better type safety #1722

Closed

Description

@spencerbeggs

Currently, the ChangelogFunctions interface uses loose typing for the changelogOpts parameter (Record<string, any> or any), which forces changelog plugin authors to work around type safety issues.

Current types:

export type GetReleaseLine = (
  changeset: NewChangesetWithCommit, 
  type: VersionType, 
  changelogOpts: null | Record<string, any>
) => Promise<string>;

export type GetDependencyReleaseLine = (
  changesets: NewChangesetWithCommit[], 
  dependenciesUpdated: ModCompWithPackage[], 
  changelogOpts: any
) => Promise<string>;

export type ChangelogFunctions = {
  getReleaseLine: GetReleaseLine;
  getDependencyReleaseLine: GetDependencyReleaseLine;
};

Proposed Enhancement

Add generic type parameters with sensible defaults to improve type safety while maintaining backward compatibility:

export type DefaultChangelogOptions = null | Record<string, any>;

export type GetReleaseLine<ChangelogOptions = DefaultChangelogOptions> = (
  changeset: NewChangesetWithCommit,
  type: VersionType,
  changelogOpts: ChangelogOptions
) => Promise<string>;

export type GetDependencyReleaseLine<ChangelogOptions = DefaultChangelogOptions> = (
  changesets: NewChangesetWithCommit[],
  dependenciesUpdated: ModCompWithPackage[],
  changelogOpts: ChangelogOptions
) => Promise<string>;

export type ChangelogFunctions<ChangelogOptions = DefaultChangelogOptions> = {
  getReleaseLine: GetReleaseLine<ChangelogOptions>;
  getDependencyReleaseLine: GetDependencyReleaseLine<ChangelogOptions>;
};

Benefits

  1. Type Safety: Plugin authors can specify exact option types (e.g., ChangelogFunctions<{ repo: string }>)
  2. Backward Compatibility: Default generic parameter maintains existing behavior
  3. Better DX: IDE autocomplete and type checking for plugin options
  4. Eliminates Workarounds: No need for complex type gymnastics with Parameters<> and ReturnType<>

Current Workaround

Plugin authors currently need to create wrapper types:

type CustomGetReleaseLine = (
  changeset: Parameters<GetReleaseLine>[0],
  versionType: Parameters<GetReleaseLine>[1],
  options: { repo: string } | null,
) => ReturnType<GetReleaseLine>;

With Proposed Enhancement

Clean, direct usage:

export const getReleaseLine: GetReleaseLine<{ repo: string }> = async (changeset, versionType, options) => {
  // options is now properly typed as { repo: string }
};

const changelog: ChangelogFunctions<{ repo: string }> = {
  getDependencyReleaseLine,
  getReleaseLine,
};

Migration Path

This would be a non-breaking change:

  • ✅ Existing code continues to work unchanged
  • ✅ New code can opt into stricter typing
  • ✅ Library consumers can gradually adopt the enhanced types

Use Case

This enhancement would particularly benefit changelog plugins that require specific configuration options (like repository information for GitHub integration), allowing them to provide better type safety and developer experience.

Example Real-World Impact

Many changelog plugins need structured options:

// Repository info for GitHub links
type GitHubOptions = { repo: string };

// Custom formatting options
type FormattingOptions = { 
  repo: string; 
  includeAuthors?: boolean; 
  linkPRs?: boolean; 
};

// Plugin-specific configuration
type CustomOptions = {
  repo: string;
  template?: string;
  categories?: Record<string, string[]>;
};

With the proposed generic types, these plugins can provide full type safety without complex workarounds.

Activity

  1. added 3 commits that reference this issue on Sep 4, 2025
    ef037e6
    5079591
    5273f58
  2. bluwy commented on Jun 15, 2026

    @bluwy
    Member

    Fixed in #2040

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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