0

Yo, everybody! I'm just curious of how I got this to work but I really don't know why it works. Can any one give some techinical explanation?

import { createContext } from 'react'

interface IContext {
  state: any
  dispatch: any
}

export interface ITodoProps {
  todos: [{ id: number; title: string }]
}

export const TodoContext = createContext<IContext>({} as IContext)

If I don't type my empty object with as IContext, Typescript gets REALLY mad at me and I don't know why. Is there some thechinical reason for the particular behaviuour?

  • “typing it with `as`” is called “making a [type assertion](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions)” or “asserting a type” – jsejcksn Mar 07 '22 at 22:36

2 Answers2

2

The error is because your empty object doesn't contain state or dispatch properties.

To change the interface so that an empty object would be allowed, you can make the properties optional:

interface IContext {
  state?: any
  dispatch?: any
}
jtbandes
  • 115,675
  • 35
  • 233
  • 266
  • Right, got it, but the main "issue" is my poor understanding of how it works just by defining my empty object "as IContext", it is a Typescript lack of knowledge from me – Fernando Soares Mar 07 '22 at 22:41
  • Using `as IContext` is like telling the TypeScript compiler "trust me, this is an IContext, I know what I'm doing". It no longer fully verifies that the object actually conforms to the interface. – jtbandes Mar 08 '22 at 17:16
0

The context expects an initial value and in this case you're passing an empty object, as @jtbandes mentioned you could set those attributes optional and passing an empty object will work, but I would say initializing the state to an empty object is not something that you would normally do in react, I'd rather do something like this and take advantage of the null in JS:

import { createContext } from "react";

interface IContext {
  state: any;
  dispatch: any;
}

export interface ITodoProps {
  todos: [{ id: number; title: string }];
}

export const TodoContext = createContext<IContext | null>(null);

This part createContext<IContext | null>(null) is the one that changes and is expecting the initial value that can be null or the interface IContext and in that way you just need to validate if the context value is not null in order to use it, without having to validate every time if the object.property exists.

jean182
  • 3,213
  • 2
  • 16
  • 27