1

This question is specific to arrow functions. Is it possible to include the default values alongside an interface in the function parameters, and without resorting to Object.assign()?

interface Props {
  someBoolean?: boolean;
  anotherBoolean?: boolean;
  children: any;
}

const DefaultValues = {
  someBoolean: false,
  anotherBoolean: false,
}

export const StackOverflow: React.FC<Props> = (_props: Props) => {
  const props = Object.assign({}, _props, DefaultValues);

  return <React.Fragment>{props.children}</React.Fragment>;
};
1
  • 1
    const props = Object.assign({}, _props, DefaultValues); does not seem correct. DefaultValues will overwrite every existing prop in _props . Should change the order to Object.assign({}, DefaultValues, _props); Commented Jun 20, 2020 at 19:15

3 Answers 3

1

You can provide the defaults in a functional way, by composing your component.

interface Props {
  someBoolean: boolean;
  anotherBoolean: boolean;
  children: any;
}

const StackOverflow: React.FC<Props> = (props: Props) => {
  return <React.Fragment>{props.children}</React.Fragment>;
};

function withDefaults<T extends React.ComponentType<any>, U extends Partial<React.ComponentProps<T>>>(
  Component: T,
  defaults: U,
): React.FunctionComponent<Omit<React.ComponentProps<T>, keyof U> & Partial<U>> {
  // @see https://github.com/Microsoft/TypeScript/issues/14729
  return props => React.createElement(Component, { ...defaults, ...props });
}

Usage:

const StackOverflowWithDefaults = withDefaults(StackOverflow, { someBoolean: false, anotherBoolean: false });

<StackOverflowWithDefaults>
  The only prop I need to provide is children
</StackOverflowWithDefaults>
Sign up to request clarification or add additional context in comments.

Comments

1

IFF you don't need DefaultValues elsewhere and you don't need to be able to refer to (all of the) props in the body of your function, then yes:

export const StackOverflow: React.FC<Props> = ({ someBoolean = false,
  anotherBoolean = false, children = [], ...additionalProps }) => {

  return <React.Fragment>{children}</React.Fragment>;
};

3 Comments

Actually you can refer to props using spread properties { someBoolean = false, anotherBoolean = false, children = [], ...props }
@SeanVieira Thank you for your reply. Could you explain why you use the interface for React.FC<Props> but not in the parameter setup, like this ({someBoolean = false, ...additionalProps}: Props)?
Because the type of React.FC<T> approximates T => ReactElementTypes and if any function definition is going to match that type signature it must either be () => ReactElementTypes (take no arguments) or take a single argument of the type T. And if the argument must be T, then there's no point (in my mind) of saying the same thing twice. ("The variable StackOverflow is a function from MyPropType to Element, to which we assign a function which takes a MyPropType and returns Element", vs. "The variable StackOverflow is a function from MyPropType to Element").
0

Answer is no. You cannot add some default value to an interface or type

But you can do something like this.

interface SomeType {
     prop1: string;
     prop2: number;
     prop3?: boolean; // optional
}

const fun = (value: SomeType) => {

// Assigning default value to the prop3 which is optional.
   const {prop1, prop2, prop3 = false} = value;

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.