Typescript UseContext React - reactjs

I'm new to Typescript and react and am getting this error, on default card
I am trying to setup use context and will use it with use state or use reducer but I am having trouble wrapping my head around initial setup for this
Error:
Argument of type '{ cartitem: { id: number; name: string; description: string; price: string; }; addCart: () => void; removeCart: () => void; }' is not assignable to parameter of type 'CartContextType'.
Types of property 'cartitem' are incompatible.
Type '{ id: number; name: string; description: string; price: string; }' is missing the following properties from type 'ICart[]': length, pop, push, concat, and 29 more.ts(2345)
import React, { createContext } from 'react';
export interface ICart {
id: number;
name: string;
description: string;
price: string;
}
export type CartContextType = {
cartitem: ICart[];
addCart: (cart: ICart, totalAmount:number) => void;
removeCart: (id: number) => void;
};
const defalutCart={cartitem:{
id: 0,
name: 'string',
description: 'string',
price: 'string'},
addCart: () => {},
removeCart: () => { }
}
export const CartContext = createContext<CartContextType | null>(defalutCart);

Your variable defalutCart needs the property cartitem to be an array. With the correct spelling and changes, here is your updated code:
const defaultCart = {
cartitem: [
{
id: 0,
name: "string",
description: "string",
price: "string",
},
],
addCart: () => {},
removeCart: () => {},
};
Do you see how the object is now wrapped in an array? Please mark this as correct if it solves your problem.

Related

Argument of type '{ id: number; color: string; }[]' is not assignable to parameter of type 'SetStateAction<never[]>'

I get these error. what do i do?
`
import React, { useState } from "react";
import "./App.css";
import { Button } from "#mui/material";
//declaring the colors
const colorSequence = [
{ "color": "#3db44b" },
{ "color": "#bfef45" },
{ "color": "#42d3f4" },
{ "color": "#4263d8" },
{ "color": "#f68232" },
{ "color": "#fee118" },
{ "color": "#e6194a" },
{ "color": "#f032e6" },
{ "color": "#921eb3" }
]
function App() {
const [colors, setColors] = useState([])
//shuffle the colors
const shuffleColors = () => {
const shuffledColors = [...colorSequence]
.sort(() => Math.random() - 0.5)
.map((color) => ({ ...color, id: Math.random() }))
setColors(shuffledColors)
}
setColors(shuffledColors) returns an error of
Argument of type '{ id: number; color: string; }[]' is not assignable to parameter of type 'SetStateAction<never[]>'.
Type '{ id: number; color: string; }[]' is not assignable to type 'never[]'.
Type '{ id: number; color: string; }' is not assignable to type 'never'.ts(2345)
[![enter image description here](https://i.stack.imgur.com/1nWXL.png)](https://i.stack.imgur.com/1nWXL.png)
You're missing the type definition of the colors stateful variable.
const [colors, setColors] = useState<{ color: string, id: number }[]>([]);
Argument of type '{ id: number; color: string; }[]' is not assignable to parameter of type 'SetStateAction<never[]>'
You are missing the type when setting the state.
const [colors, setColors] = useState<{ color: string; id?: number }[]>([]);
Typescript playground
You're missing the type definition of the colors state variable.To solved this error there is two way.
1st way
const [colors, setColors] = useState<{ color: string, id: number }[]>([]);
2nd way
Follow Below 2 steps:
make one interface of colors like below.
interface colors
{
color: String,
id: Number
}
Assign interface to the state.
const [colors, setColors] = useState< colors >([])

Any insights on why my type is not being properly used in the generic function?

Code Example in ReactJS:
The record type being rendered in the render function can vary depending upon the application. This seemed like the perfect use case for a generic. Any ideas why this doesn't work as I expected?
type Column = {
title?: string;
key: string;
className?: string;
sort?: boolean;
isVisible?: boolean;
render?: <Type>(record: Type) => ReactNode;
};
type Customer = {
customerAddress: { street1: string };
};
const columns: Column[] = [
{
title: "Street Address",
key: "customerAddress.street1",
sort: true,
filter: {
type: "string",
},
render: function <Customer>(record: Customer) {
return record?.customerAddress?.street1;
},
},
];
I get the following error:
any
Property 'customerAddress' does not exist on type 'NonNullable<Customer>'.ts(2339)
I was expecting customerAddress to exist in the definition.
Thanks in advance!
A generic function needs to be able to handle any type argument passed in by the caller (see this video for an explanation
What you really want is to make the Column type generic:
type Column<Type> = {
title?: string;
key: string;
className?: string;
sort?: boolean;
isVisible?: boolean;
render?: (record: Type) => ReactNode;
};
type Customer = {
customerAddress: { street1: string };
};
const columns: Column<Customer >[] = [
{
title: "Street Address",
key: "customerAddress.street1",
sort: true,
render: function (record: Customer) {
return record?.customerAddress?.street1;
},
},
];
Playground Link

Getting error on updating boolean state in Redux

My state data:
options: [
{
id: 1,
name: "Sale",
isTrue: false,
},
{
id: 2,
name: "New in",
isTrue: false,
},
],
And, in reducers I have:
closeOptions: (state) => {
state.options = state.options.map((item) => (item.isTrue = false));
},
But I am getting error in state.options with red underline in vscode. And, it shows below error:
Type 'boolean[]' is not assignable to type 'WritableDraft<{ id: number; name: string; isTrue: boolean; }>[]'.
Type 'boolean' is not assignable to type 'WritableDraft<{ id: number; name: string; isTrue: boolean; }>'.ts(2322)
More,
Unhandled Runtime Error
TypeError: Cannot create property 'isTrue' on boolean 'false'
Source
105 | closeOptions: (state) => {
> 106 | state.options = state.options.map((item) => (item.isTrue = false));
| ^
107 | },
How can I resolve this issue?
Whole project in TS
You're getting these errors:
Type 'boolean[]' is not assignable to type 'WritableDraft<{ id: number; name: string; isTrue: boolean; }>[]'.
Type 'boolean' is not assignable to type 'WritableDraft<{ id: number; name: string; isTrue: boolean; }>'.ts(2322)
Because when you use state.options.map((item) => (item.isTrue = false)) in closeOptions it's returning [false, false] whose type is boolean[] which is completely different from type WritableDraft<{ id: number; name: string; isTrue: boolean; }>[].
Change closeOptions function to this:
closeOptions: (state) => {
state.options?.forEach((item) => (item.isTrue = false))
}
If you are using Redux Toolkit, you can simply do:
closeOptions: (state) => {
state.options.forEach((item) => {
item.isTrue = false;
});
},

Property 'options' is optional in type '{ question: number , label: string; ...etc}' but required in type '{ question: any; label: string, etc.}

I'm working with React and Typescript. I'm getting the following error in my terminal and it's not clear what I'm doing wrong.
TS2322: Type '{ question: number; label: string; prop: string; type: string; style: string; placeholder?: string; options?: any; }' is not assignable to type '{ question: any; label: any; prop: any; style: any; type: any; options: any; }'.
Property 'options' is optional in type '{ question: number; label: string; prop: string; type: string; style: string; placeholder?: string; options?: any; }' but required in type '{ question: any; label: any; prop: any; style: any; type: any; options: any; }'.
Below is the relevant code. Notice I got this error before I used an interface as well as after creating one. The error is happening with my Dropdown component inside of the formGroup component below. What am I doing wrong?
// formGroup Component
const myForm: Form = FORM.step_1;
const FormGroup = props => {
const test = '';
return (
<div>
{myForm.controls.map(form => {
if (form.type === 'text') {
return (
<TextInput
{...form}
/>
);
}
if (form.type === 'dropdown') {
return (
<Dropdown
{...form}
/>
);
}
})}
</div>
);
};
export default FormGroup;
// dropdown component
interface IFormInput {
gender: GenderEnum;
}
enum GenderEnum {
female = "female",
male = "male",
other = "other",
}
const Dropdown = ({
question,
label,
prop,
style,
type,
options,
}) => {
const { register, handleSubmit } = useForm<IFormInput>();
const onSubmit: SubmitHandler<IFormInput> = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<label>{question && `${question}.`} {label}</label>
<select {...register("gender")}>
<option value="female">female</option>
<option value="male">male</option>
<option value="other">other</option>
</select>
<input type="submit" />
</form>
);
};
export default Dropdown;
// data object
export interface Form {
step_1: Controls
}
export interface Controls {
controls: Array<FormConfiguration>
}
export interface FormConfiguration {
question: number;
label: string;
prop: string;
type: string;
style: string;
placeholder?: string;
options?: any;
}
export const FORM: Form = {
step_1: {
controls: [
{
question: 75, // should this be a key or id?
label: 'Primary federal regulator',
prop: '',
style: '',
type: 'dropdown',
placeholder: 'Select a category',
options: [
{
label: 'FCC',
value: 'FCC',
},
{
label: 'FDA',
value: 'FDA',
},
],
},
{
question: 76,
label: 'Filer name (Holding compnay, lead financial institution, or agency, if applicable)',
prop: '',
style: '100%',
type: 'text',
},
{
question: 77,
label: 'TIN',
prop: '',
style: '50%',
type: 'text',
},
{
question: 78,
label: 'TIN type',
prop: '',
style: '50%',
type: 'text',
},
{
question: 80,
label: 'Type of Securities and Futures institution of individual filing this report - check box(es) for functions that apply to this report',
prop: '',
style: '',
type: 'checkbox',
options: [
{
label: 'Clearing broker-securities',
value: 'clearing broker-securities',
},
{
label: 'CPO/CTA',
value: 'CPO/CTA',
},
],
},
],
},
};
Your Dropdown component expects options as one of its props. You can either add a default value to make it optional, or fully type the props of the component, marking options as optional.
Approach #1 - default value:
const Dropdown = ({
question,
label,
prop,
style,
type,
options = [],
})
Approach #2 - typed props:
type Option = {
label: string;
value: string;
};
type Props = {
question: number;
label: string;
prop: string;
style: string;
type: string;
options?: Option[]; // note the question mark, which marks the prop as optional
...
};
const Dropdown = ({
question,
label,
prop,
style,
type,
options,
}: Props)
PS. I noticed you already have a type FormConfiguration (albeit options is using any which should be avoided). You can use that for the component by replacing : Props with : FormConfiguration in the example #2 above.
I managed to reproduce your problem in a much shorter example
interface FormConfiguration {
question: string
options?: any;
}
const simpleForm:FormConfiguration = {
question: "why options is required?"
}
function print({question, options}){
console.log(question, options);
}
function print_working({question, options}:FormConfiguration){
console.log(question, options);
}
print(simpleForm); // has you problem
print_working(simpleForm); //problem resolved
full code Playground Link
so the solution for you is to define the type of Dropdown function arguments. DropDown = ({...}: FormConfiguration)

Type 'undefined' is not assignable to type 'DataProps'

I am new to typescript with reactjs. Here I tried to display data which is coming from data file which looks something like this see below.
After this I am grabing object with same id and display that object on screen for that I used destructuring of object like this.
Here type script is complaining about types which i have added but still error is not going away.
Error Type '{ id: number; img: any; title: string; subtitle: string; price: number; } | undefined' is not assignable to type 'DataProps'.
Type 'undefined' is not assignable to type 'DataProps'.
interface DataProps {
img: ImageSourcePropType;
title: string;
subtitle: string;
}
const productId = route.params.productId;
const dataDisplay = data.find((el, index) => {
if (el.id !== productId) {
return undefined;
} else {
return el.id === productId;
}
});
const { img, title, subtitle }: DataProps = dataDisplay; <--- here typescript is complaining about
dummydata.ts
export const data = [
{
id: 1,
img: require("../../assets/food-1.png"),
title: "Pizza",
subtitle: "With Beef Mushroom",
price: 12,
},
{
id: 2,
img: require("../../assets/food-2.png"),
title: "Pizza",
subtitle: "With Beef Mushroom",
price: 12,
},

Resources