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

[v2.2.1] Auth0Plugin is incompatible with Auth0VueClient (exactOptionalPropertyTypes: true) #240

Closed
6 tasks done
SimonSimCity opened this issue Jul 10, 2023 · 10 comments · Fixed by #243
Closed
6 tasks done
Labels
bug This points to a verified bug in the code needs investigation An issue that has more questions to answer or otherwise needs work to fully understand the issue

Comments

@SimonSimCity
Copy link

Checklist

  • The issue can be reproduced in the auth0-vue sample app (or N/A).
  • I have looked into the Readme, Examples, and FAQ and have not found a suitable solution or answer.
  • I have looked into the API documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have searched the Auth0 Community forums and have not found a suitable solution or answer.
  • I agree to the terms within the Auth0 Code of Conduct.

Description

After updating to v2.2.1, my typscript compiler complains when assigning a value of type Auth0Plugin to a variable defined as type Auth0VueClient.

Error:

plugins/1.auth0.server.ts:10:5 - error TS2322: Type 'Auth0Plugin' is not assignable to type 'Auth0VueClient'.
  The types of 'user.value' are incompatible between these types.
    Type '{ readonly [x: string]: any; readonly name?: string | undefined; readonly given_name?: string | undefined; readonly family_name?: string | undefined; readonly middle_name?: string | undefined; ... 15 more ...; readonly sub?: string | undefined; } | undefined' is not assignable to type 'User | undefined'.
      Type '{ readonly [x: string]: any; readonly name?: string | undefined; readonly given_name?: string | undefined; readonly family_name?: string | undefined; readonly middle_name?: string | undefined; ... 15 more ...; readonly sub?: string | undefined; }' is not assignable to type 'User' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
        Types of property 'name' are incompatible.
          Type 'string | undefined' is not assignable to type 'string'.
            Type 'undefined' is not assignable to type 'string'.

The types of the values user of the interface Auth0VueClient and the class Auth0Plugin are incompatible in that the class defines it as:

export declare class Auth0Plugin implements Auth0VueClient {
    private clientOptions;
    private pluginOptions?;
    private _client;
    private _isLoading;
    private _isAuthenticated;
    private _user;
    private _idTokenClaims;
    private _error;
    isLoading: Readonly<Ref<boolean>>;
    isAuthenticated: Readonly<Ref<boolean>>;
    user: Readonly<Ref<{
        readonly [x: string]: any;
        readonly name?: string | undefined;
        readonly given_name?: string | undefined;
        readonly family_name?: string | undefined;
        readonly middle_name?: string | undefined;
        readonly nickname?: string | undefined;
        readonly preferred_username?: string | undefined;
        readonly profile?: string | undefined;
        readonly picture?: string | undefined;
        readonly website?: string | undefined;
        readonly email?: string | undefined;
        readonly email_verified?: boolean | undefined;
        readonly gender?: string | undefined;
        readonly birthdate?: string | undefined;
        readonly zoneinfo?: string | undefined;
        readonly locale?: string | undefined;
        readonly phone_number?: string | undefined;
        readonly phone_number_verified?: boolean | undefined;
        readonly address?: string | undefined;
        readonly updated_at?: string | undefined;
        readonly sub?: string | undefined;
    } | undefined>>;

... but the interface refers to the class User which is defined as:

export declare class User {
    name?: string;
    given_name?: string;
    family_name?: string;
    middle_name?: string;
    nickname?: string;
    preferred_username?: string;
    profile?: string;
    picture?: string;
    website?: string;
    email?: string;
    email_verified?: boolean;
    gender?: string;
    birthdate?: string;
    zoneinfo?: string;
    locale?: string;
    phone_number?: string;
    phone_number_verified?: boolean;
    address?: string;
    updated_at?: string;
    sub?: string;
    [key: string]: any;
}

When having the option exactOptionalPropertyTypes set to true, an optional property is different to an optional property which can also be undefined.

Reproduction

  1. Setting exactOptionalPropertyTypes to true in your Typescript configuration
  2. Try to let this statement compile:
const foo = (plugin: Auth0Plugin) : Auth0VueClient => plugin

Additional context

No response

auth0-vue version

2.2.1

Vue version

3.3.4

Which browsers have you tested in?

Other

@SimonSimCity SimonSimCity added the bug This points to a verified bug in the code label Jul 10, 2023
@SimonSimCity SimonSimCity changed the title [v2.2.1] Auth0Plugin is incompatible with Auth0VueClient [v2.2.1] Auth0Plugin is incompatible with Auth0VueClient (exactOptionalPropertyTypes: true) Jul 10, 2023
@frederikprijck
Copy link
Member

Thanks, I can reproduce this and will look into a fix for this.

@frederikprijck frederikprijck added the needs investigation An issue that has more questions to answer or otherwise needs work to fully understand the issue label Jul 13, 2023
@jonasingvar
Copy link

@SimonSimCity which version did you upgrade from? I'm seeing the same error and trying to figure the last working version. thanks

@SimonSimCity
Copy link
Author

SimonSimCity commented Jul 14, 2023

@jonasingvar I'm back on v2.2.0, which doesn't give you a hint that the property user can also be undefined (see #235 which was added in v2.2.1)

@frederikprijck
Copy link
Member

frederikprijck commented Jul 14, 2023

I opened a PR that I believe should solve this. The change might be a bit different as you would expect, but I believe it makes sense and elaborated on it in the PR: #243 .

Could you verify it solves your compilation issues by doing:

  • git clone --branch fix/240 git@github.com:auth0/auth0-vue.git
  • cd auth0-vue
  • npm install
  • npm pack

The above commands result in a file called auth0-auth0-vue-2.2.1.tgz in the root. Then in your application that uses our SDK, you can do:

  • npm uninstall @auth0/auth0-vue
  • npm install ../path/to/auth0-auth0-vue-2.2.1.tgz

After that, can you try compiling your application and see if it solves the problem?

@SimonSimCity
Copy link
Author

@frederikprijck I have to see and investigate how this could solve the problem I'm facing here ... As far as I understand the problem, it's not that some are read-only and others not, it's that their types are incompatible.

Auth0Plugin.user.name can exist and be undefined wereas Auth0VueClient.user.name, the one it inherits from, cannot exist and be undefined - that's the problem as I understand it.

This would be either solved by allowing the properties on the class User to be undefined or by disallowing the properties on Auth0Plugin.user to be undefined, as they are on User.

The above should yield regardless of whether they're read-only or not.

I'll nevertheless take the time to check out your changes and see how it affects my code.

@frederikprijck
Copy link
Member

Yeah I understand what you mean. The thing is, one of the two incorrect types (the one for Auth0Plugin.user) comes from using readonly(), and we rely on letting TypeScript find out what the return value of that is.

We could cast the response from readonly(): user = readonly(this._user) as Ref<User | undefined>. Even though this could solve the error, it doesn't contain the readonly properties. Therefore, we might need to have an additional type to represent the readonly variant of User. But still, we'd be tricking TypeScript with the cast.

We could do that, but the question is for what? There isn't a real need for using readonly() from the looks of it, and I feel like it might be an easier way to just avoid using readonly() rather than try fix the types by using it while not actually needed.

We could also opt for changing the types in the User (and IdTokenClaims) to be:

name?: string | undefined;

However, this is a type from outside this SDK. Even though we could update that, it's worth asking ourselves if that's what we want if we know the readonly() might not be something we actualy need to use.

@jonasingvar
Copy link

PR #243 fixes it for me. I can now successfully run npm run build.

@frederikprijck
Copy link
Member

Any chance you have found the time to give the PR a try @SimonSimCity ? Thanks!

@SimonSimCity
Copy link
Author

Tested, works 😎👍 I've also created a bug-report in the repo for typescript 😊 microsoft/TypeScript#55058

@frederikprijck
Copy link
Member

Thanks, I think strictly speaking we may want to update the types to be:

interface User {
  name?: string | undefined;
}

So I would assume that might be their response. We can still do that eventually, as I think it might be better. I just felt like removing readonly could be the better decision here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This points to a verified bug in the code needs investigation An issue that has more questions to answer or otherwise needs work to fully understand the issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants