Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Context.Tag unification #4419

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

KhraksMamtsov
Copy link
Contributor

Type

  • Refactor
  • Feature
  • Bug Fix
  • Optimization
  • Documentation Update

Description

Related

  • Related Issue #
  • Closes #

Copy link

changeset-bot bot commented Feb 7, 2025

🦋 Changeset detected

Latest commit: aa64445

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 35 packages
Name Type
effect Patch
@effect/cli Patch
@effect/cluster-browser Patch
@effect/cluster-node Patch
@effect/cluster-workflow Patch
@effect/cluster Patch
@effect/experimental Patch
@effect/opentelemetry Patch
@effect/platform-browser Patch
@effect/platform-bun Patch
@effect/platform-node-shared Patch
@effect/platform-node Patch
@effect/platform Patch
@effect/printer-ansi Patch
@effect/printer Patch
@effect/rpc-http Patch
@effect/rpc Patch
@effect/sql-clickhouse Patch
@effect/sql-d1 Patch
@effect/sql-drizzle Patch
@effect/sql-kysely Patch
@effect/sql-libsql Patch
@effect/sql-mssql Patch
@effect/sql-mysql2 Patch
@effect/sql-pg Patch
@effect/sql-sqlite-bun Patch
@effect/sql-sqlite-do Patch
@effect/sql-sqlite-node Patch
@effect/sql-sqlite-react-native Patch
@effect/sql-sqlite-wasm Patch
@effect/sql Patch
@effect/typeclass Patch
@effect/vitest Patch
@effect/ai Patch
@effect/ai-openai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@KhraksMamtsov
Copy link
Contributor Author

@mikearnaldi
I investigated the issue and concluded that TypeScript fails to infer types, for example, in the case of Layer.succeed used with this in class body(It looks like a shortcoming on Typescript's side because it works if the function is used outside the class body).

The issue can be resolved by using type parameters directly instead of inferring them from the provided tag — this approach is used in Micro(https://github.com/Effect-TS/effect/blob/main/packages/effect/src/Micro.ts#L1835) and other modules.

// before
export const succeed: {
  <T extends Context.Tag<any, any>>(tag: T): (resource: Context.Tag.Service<T>) => Layer<Context.Tag.Identifier<T>>
  <T extends Context.Tag<any, any>>(
    tag: T,
    resource: Context.Tag.Service<T>
  ): Layer<Context.Tag.Identifier<T>>
} = internal.succeed
// after 
export const succeed: {
  <I, S>(tag: Context.Tag<I, S>): (resource: S) => Layer<I>
  <I, S>(tag: Context.Tag<I, S>, resource: S): Layer<I>
} = internal.succeed

This approach seems more correct since type parameters are invariant, and union tags cannot be unified into a tag of unions.

However, this would be a breaking change, though it might be reasonable to treat it as a bug fix.
What do you think? I'm not sure whether the use case for unification is common enough to justify fixing it at the cost of a breaking change. On the other hand, I believe this change is theoretically correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Discussion Ongoing
Development

Successfully merging this pull request may close these issues.

1 participant