question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

DefaultValue type forcing me to check the type before using the property

See original GitHub issue

I think this issue should be addressed by @csantos42’s DefinitelyTyped, but I’m not sure where to submit this issue. If anyone could point me out where should be best I will be glad.

In this example I have the usage of a selector called “userState” that uses a atom called “userAtom” and it’s function is to save a cache from the atom new value on localStorage and saves a bearer token inside Axios default header Authorization:

export const userState = selector<IUser | null>({
  key: "userState",
  get: ({ get }) => {
    return get(userAtom);
  },
  set: ({ set }, user) => {
    if (user !== null) {
      Axios.defaults.headers.Authorization = `Bearer ${user.token}`;
      localStorage.setItem(ls("userState"), JSON.stringify(user));
    } else {
      localStorage.removeItem(ls("userState"));
    }
    set(userAtom, user);
  },
});

The problem is that TypeScript is complaining that “token” used here is not a DefaultValue’s property:

     Axios.defaults.headers.Authorization = `Bearer ${user.token}`;

TS2339: Property 'token' does not exist on type 'DefaultValue | IUser'. Property 'token' does not exist on type 'DefaultValue'.

But I expect that TypeScript only checks the type I informed here:

export const userState = selector<IUser | null>({

My suggestion is to change this type:

export interface ReadWriteSelectorOptions<T> extends ReadOnlySelectorOptions<T> {
    set: (
        opts: {
            set: SetRecoilState;
            get: GetRecoilValue;
            reset: ResetRecoilState;
        },
        newValue: T | DefaultValue,
    ) => void;
}

to

export interface ReadWriteSelectorOptions<T = DefaultValue> extends ReadOnlySelectorOptions<T> {
    set: (
        opts: {
            set: SetRecoilState;
            get: GetRecoilValue;
            reset: ResetRecoilState;
        },
        newValue: T,
    ) => void;
}

Then the DefaultValue type is only used when I don’t inform any type to the selector usage.

For now my workaround was to check the value’s type:

      if (!(user instanceof DefaultValue)) {
        Axios.defaults.headers.Authorization = `Bearer ${user.token}`;
      }

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
bnayaecommented, Dec 4, 2020

If you’re using typesctipt, you can use the following (guard)

import { DefaultValue } from 'recoil';

export const guardRecoilDefaultValue = (
  candidate: any
): candidate is DefaultValue => {
  if (candidate instanceof DefaultValue) return true;
  return false;
};

This is how you use it:

if (guardRecoilDefaultValue(post)) return; // excluding the DefaultValue from the type options

// here it will be the type you're looking for 
set(postIdFiledAtom(id), post.id);
0reactions
rajeshbabu-ovivacommented, Oct 21, 2021

I bumped into the same problem and used ‘as’ to type cast the value, if you do not want to reset the selector with DefaultValue

export const stepValueSelectorFamily = selectorFamily<StepValue | null, number>({
  key: 'stepValueSelectorFamily',
  get:
    (stepId) => someValue,
  set:
    (stepId) =>
    ({ set }, newStepValue) => {
      set(flowExecutionAtom, (previousState) => {
        const stepValues = getStepValues();
        const stepIndex = getStepIndex()
        if (stepValueIndex !== -1) {
          stepValues[stepValueIndex] = newStepValue as StepValue;
        }

        return { ...previousState, stepValues };
      });
    },
});
Read more comments on GitHub >

github_iconTop Results From Across the Web

Default value for typescript type alias - Stack Overflow
The error is A type literal property cannot have an initializer. I can't find documentation relating to this - type keyword is very...
Read more >
How to fix property validation and its implicit default values?
My problem is, that a restriction in both class and dimension does force a default value which satisfies them. The result is, that...
Read more >
DefaultValue Property - Microsoft Support
The DefaultValue property applies to all table fields except those fields with the data type of AutoNumber or OLE Object. The DefaultValue property...
Read more >
How to get the default Value (.defval) of Enumeration type? - IBM
My question is:how do I gethereforsuchan"enumerated"attribute typethe"defaultvalue"back,ieI needa property/methodthatreturns methestring"white" inthat case.
Read more >
Swift Associated Types With Default Values - SwiftRocks
As the feature implies, setting a default value for an associated type will allow the children of the protocol to skip having to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found