eozzy
eozzy

Reputation: 68720

'string' only refers to a type, but is being used as a value here

New to TypeScript. I'm trying to set state but getting this error.

Error: 'string' only refers to a type, but is being used as a value here.

const state = reactive({
    user: {
        uid: "",
        provider: string[],
    }
});

const user = auth.currentUser;
if (user != null) {
    state.user.uid = user.uid || "";
    user.providerData.forEach(function(profile) {
        state.user.provider.push({
            providerId: profile.providerId,
            uid: profile.uid,
        })
    });
}

Upvotes: 12

Views: 57010

Answers (2)

samthecodingman
samthecodingman

Reputation: 26246

Based on just this statement:

const state = reactive({
    user: {
        uid: "",
        provider: string[],
    }
});

You've written it with the intention of giving the provider property a type of string[], but in this statement it is trying to set the value (not type) of the variable and because string[] is not a value, it throws the error. To set the value of provider to an array, that has a type of string[], you would use:

const state = reactive({
    user: {
        // initialize as "", type is automatically set to string
        uid: "",

        // create array and override its type to an array of strings
        provider: [] as string[], 
    }
});

However, when we look at how you are using this state variable:

const user = auth.currentUser;
if (user != null) {
    state.user.uid = user.uid || "";
    user.providerData.forEach(function(profile) {
        state.user.provider.push({  // <-- this bit here is important
            providerId: profile.providerId,
            uid: profile.uid,
        })
    });
}

In these lines you are pushing an object of type { providerId: string, uid: string } to your state.user.provider array. This means your first bit of code actually needs to be:

const state = reactive({
    user: {
        // initialize as "", the type is automatically set to string
        uid: "", 

        // create empty array and override its type to an array of { providerId: string, uid: string } objects
        provider: [] as ({ providerId: string, uid: string })[], 
    }
});

You can also make use of an interface to name this object shape:

interface ProviderData {
  providerId: string;
  uid: string;
}
// you could also use this similar syntax:
// type ProviderData = {
//   providerId: string;
//   uid: string;
// }

const state = reactive({
    user: {
        // initialize as "", the type is automatically set to string
        uid: "", 

        // create empty array and override its type to an array of ProviderData objects
        provider: [] as ProviderData[], 
    }
});

Upvotes: 15

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Create an interface called IUser then type your reactive item as follows :

interface IUser {
  user: {
    uid: string;
    provider: string[];
};
        
const state = reactive<IUser>({
  user: {
    uid: '',
    provider: [],
  },
});

Upvotes: 1

Related Questions