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: this.attribute(name) should fallback to Literal #353

Merged
merged 1 commit into from
Sep 27, 2022

Conversation

cyjake
Copy link
Owner

@cyjake cyjake commented Sep 27, 2022

class Foo {
  @Column(TEXT)
  get settings(): Record<string, any> {
    // this.attribute('settings') should return the original union type here
    const text = this.attribute('settings') as string;
    if (!text) return null;
    try {
      return JSON.parse(text);
    } catch {
      return null;
    }
  }
}

attribute<T, Key extends keyof T>(this: T, name: Key, value: T[Key]): void;
attribute<T, Key extends keyof T>(this: T, name: Key): T[Key];
attribute<T, Key extends keyof T>(this: T, name: Key, value: Literal): void;
attribute<T, Key extends keyof T, U extends T[Key]>(this: T, name: Key): U extends Literal ? U : Literal;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If U is assignable to Literal, return U, else return Literal. This shall prevent this.attribute() calls in getter gives impractical type such as object | Function.

@@ -48,7 +48,20 @@ describe('=> Basics (TypeScript)', function() {
summary: string;

@Column(TEXT)
settings: string;
get settings(): Record<string, any> {
const text = this.attribute('settings') as string;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically Record<string, any> is still assignable to LIteral but somehow this works, this.attribute('settings') returns Literal here.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might because of the extra U extends T[Key] that derives a new type from T[Key]?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems text's type is Literal | this["settings"]

```ts
class Foo {
  @column(TEXT)
  get settings(): Record<string, any> {
    // this.attribute('settings') should return the original union type here
    const text = this.attribute('settings') as string;
    if (!text) return null;
    try {
      return JSON.parse(text);
    } catch {
      return null;
    }
  }
}
```
@cyjake cyjake force-pushed the limit-attribute-return-type-literal branch from f6de25c to 4385c47 Compare September 27, 2022 09:10
@JimmyDaddy JimmyDaddy merged commit 8c1520a into master Sep 27, 2022
@JimmyDaddy JimmyDaddy deleted the limit-attribute-return-type-literal branch September 27, 2022 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants