How to assign a parameter in tsx? - javascript

I got a problem and VSCode doesn't find any errors but my browser does. The browser tells me to assign it to a parameter but I don't know if I'm just doing it wrong but after typing (parameter) before the props inside the constructor it throws errors at me. Maybe you know a solution to this problem. Thanks in regards. (Explanation of what I am doing: I want to toggle 2 flexBoxes through buttons and make them visible/invisible.
I'm using react 16.13 and typescript 3.9.7. It worked quite well but after adding the second toggle, the described problem appears)
"Argument of type '{} | Readonly<{ any: "showContent"; showMessages: any; }>' is not assignable to parameter of type '{ showContent: any; showMessages: any; } | Readonly<{ showContent: any; showMessages: any; }>'.
Type '{}' is not assignable to type '{ showContent: any; showMessages: any; } | Readonly<{ showContent: any; showMessages: any; }>'.
Type '{}' is missing the following properties from type 'Readonly<{ showContent: any; showMessages: any; }>': 'showContent', 'showMessages'"
class Explore extends React.Component<{}, IState> {
constructor(props: {} | Readonly<{ any: 'showContent' , 'showMessages' }>) {
super(props);
this.toggleContent = this.toggleContent.bind(this)
this.toggleMessages = this.toggleMessages.bind(this)
this.state = {
showContent: false,
showMessages: false
}
}
toggleContent(event: { preventDefault: () => void}) {
event.preventDefault()
this.setState({
showContent: !this.state.showContent
})
}
toggleMessages(event: { preventDefault: () => void}) {
event.preventDefault()
this.setState({
showMessages: !this.state.showMessages
})
}
render() {
const { showContent } = this.state
const { showMessages } = this.state

Related

React native ref Property 'ref' does not exist on type 'IntrinsicAttributes &

I am getting the following error but I am not able to figure out how to fix it someone can help me out.
Below is also the link on expo with the complete code.
Error on <AppIntroSlider /> which is reported by snack expo
Example:
Type '{ ref: (ref: any) => any; data: { key: string; title: string;
text: string; backgroundColor: string; }[]; renderItem: ({ item }:
any) => Element; renderPagination: (activeIndex: number) => Element;
scrollX: (scrollXList: any) => any; }' is not assignable to type
'IntrinsicAttributes & { data: any[]; renderItem: (info:
ListRenderItemInfo & { dimensions: { width: number; height:
number; }; }) => ReactNode; renderSkipButton?: (() => ReactNode) |
undefined; ... 19 more ...; scrollX?: ((a: any) => void) | undefined;
} & FlatListProps<...> & { ...; }'. Property 'ref' does not exist on
type 'IntrinsicAttributes & { data: any[]; renderItem: (info:
ListRenderItemInfo & { dimensions: { width: number; height:
number; }; }) => ReactNode; renderSkipButton?: (() => ReactNode) |
undefined; ... 19 more ...; scrollX?: ((a: any) => void) | undefined;
} & FlatListProps<...> & { ...; }'.
Link: expo
const slider = useRef(null);
...
<AppIntroSlider
ref={(ref: any) => (slider.current = ref)}
...
type ItemTProps<ItemT> = {
data: ItemT[];
renderItem: (
info: ListRenderItemInfo<ItemT> & {
dimensions: { width: number; height: number };
}
) => React.ReactNode;
renderSkipButton?: () => React.ReactNode;
renderNextButton?: () => React.ReactNode;
renderDoneButton?: () => React.ReactNode;
renderPrevButton?: () => React.ReactNode;
onSlideChange?: (a: number, b: number) => void;
onSkip?: () => void;
onDone?: () => void;
renderPagination?: (activeIndex: number) => React.ReactNode;
activeDotStyle: ViewStyle;
dotStyle: ViewStyle;
dotClickEnabled: boolean;
skipLabel: string;
doneLabel: string;
nextLabel: string;
prevLabel: string;
showDoneButton: boolean;
showNextButton: boolean;
showPrevButton: boolean;
showSkipButton: boolean;
bottomButton: boolean;
scrollX?: (a: any) => void;
} & FlatListProps<ItemT>;
const AppIntroSlider: FunctionComponent<ItemTProps<any>> = ({
data,
renderItem,
renderSkipButton,
renderNextButton,
renderDoneButton,
renderPrevButton,
onSlideChange,
onSkip,
onDone,
renderPagination,
activeDotStyle = {
backgroundColor: 'rgba(255, 255, 255, .9)',
},
dotStyle = {
backgroundColor: 'rgba(0, 0, 0, .2)',
},
dotClickEnabled = true,
skipLabel = 'Skip',
doneLabel = 'Done',
nextLabel = 'Next',
prevLabel = 'Back',
showDoneButton = true,
showNextButton = true,
showPrevButton = false,
showSkipButton = false,
bottomButton = false,
extraData,
scrollX,
...otherProps
}: any) => {
When you log slider.current ref it displayed null because your AppIntroSlider component is a functional component and doesn't support this way. you have two solutions, change AppIntroSlide to a class component and it will work fine, or use forwardRef.
I took a look at the example that you posted with useImperativeHandle and you've got it mostly right. Your usage is a little different than the one in my other answer because your function goToSlide takes arguments.
When you define the interface for the referenced component, you need to define the goToSlide function with the appropriate argument types. You currently defined it as a function that takes no arguments (goToSlide(): void) and that's why you are getting the error "Type '(pageNum: number, triggerOnSlideChange?: boolean | undefined) => void' is not assignable to type '() => void'." on the line with useImperativeHandle.
export interface MyRef {
goToSlide(pageNum: number, triggerOnSlideChange?: boolean): void;
}
A bunch of the props on MyCustomComponentProps should be defined as optional. You are already setting default value for them.
After fixing those two things, all of your errors go away except for those caused by the optional chaining ?.. This is a new-ish feature and I'm not sure how to get Expo to understand it.
You don't technically need the ?. after sliderRef because the ref object will always be defined. It's the current property that might be null, so you do need the ?. after current. But you could also check it the old-fashioned way if the red underlines bother you:
const prev = (activeIndex: number): void => {
if ( sliderRef.current ) {
sliderRef.current.goToSlide(activeIndex - 1, true);
}
};
Updated expo link

React-Redux TypeScript Errors

Tryign to implement TypeScript with React/Redux and I'm running into some issues with my Types.
I have these types:
export interface IAuthState {
isSignedIn: Boolean | null;
userId: string | null;
}
export interface IStream {
id: string;
title: string;
description: string;
userId: string;
}
export interface IStreamState {
streams: { [index: string]: IStream };
}
Then I have two components:
interface IStreamsProps {
fetchStreams: () => void;
streams: IStreamState;
currentUserId: String | null;
isSignedIn: Boolean | null;
auth: IAuthState;
}
class StreamsList extends Component<IStreamsProps, IAppState> {
// Error: The Property Map does not exist on type IStreamState
renderList() {
return this.props.streams.map((stream: IStream) => (// CODE)
}
}
const mapStateToProps = (state: IAppState) => {
return {
streams: Object.values(state.streams),
currentUserId: state.auth.userId,
isSignedIn: state.auth.isSignedIn
};
};
export default connect(
mapStateToProps,
{ fetchStreams }
)(StreamsList);
Then I have another similar component:
const mapStateToProps = (state: IAppState, ownProps: HomeProps) => {
return {
//Error: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'IStreamState'
stream: state.streams[ownProps.match.params.id]
};
};
export default connect(
mapStateToProps,
null
)(StreamEdit);
How do I solve these two errors:
Error 1: The Property Map does not exist on type IStreamState
Error 2: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'IStreamState'
You incorrectly defined IStreamState. Look closely. You've defined it as an object
export interface IStreamState {
streams: { [index: string]: IStream }[];
}
// equivalent declaration using type:
export type IStreamState = {
streams: { [index: string]: IStream }[]
}
I'm sure you mean to type it as just an array, as so:
export type IStreamState = { [index: string]: IStream }[]
EDIT:
While not directly related to your question, you need to be careful with your types. I noticed you used IAppState in two different places. The class declarations are for props and local state. IAppState appears to be for your redux store.
// the second generic argument is for `this.state`
class StreamsList extends Component<IStreamsProps, IAppState> {
EDIT2:
Defining both arguments in a class is optional. If you leave the second one out, it defaults to {} for you.
It's impossible to be 100% sure as to why you're having that issue in your mapStateToProps, because I don't know what IAppState looks like. Just go double back and confirm your typing for state.streams is exactly what you expect.

Typescript React generic function type

I have a case:
interface State {
Mark: boolean;
Jane: boolean;
}
React.Component<{}, State> {
state = {
Mark: false,
Jane: false,
};
fn = (name: string) => () => {
this.setState({ [name]: true });
^^^^^^^^^^
}
render () {
return
['Mark', 'Jane'].map((name) => <div onClick={this.fn(name)}>{name}</div>);
}
Im getting error:
Argument of type '{ [x: string]: boolean; }' is not assignable
to parameter of type 'State | Pick<State, "Mark" | "Jane">
I could do two separate functions for it, but I want to keep it generic. How could I make it generic so the error goes off?
It turns out this is a limitation of the ts compiler itself. Check this issue for more on that: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/26635
Now to solve your problem you can use setState with a callback version. Like bellow:
interface State {
Mark: boolean;
Jane: boolean;
}
type StateKeys = keyof State
class Test extends React.Component <{}, State > {
state = {
Mark: false,
Jane: false,
};
fn = (name: StateKeys) => () => {
this.setState(prev => ({ ...prev, [name]: true }));
}
render() {
return ['Mark', 'Jane'].map((name: StateKeys) => <div onClick={this.fn(name)}>{name}</div>);
}
}

React HoC inject props with typescript

I have a react HoC which is add two params (function to translate and current locale) into component props. It's works good. But i start rewrite project with TypeScript, and i have no idea how to do that.
My point is very similar as how-to-handle-props-injected-by-hoc-in-react-with-typescript. But i have one more HoC into my HoC.
import React from 'react';
import PropTypes from 'prop-types';
import { injectIntl } from 'react-intl';
export function withTranslate(Component) {
function WithTranslate(props) {
const { intl, ...compProps } = props;
const translate = key => {
return intl.formatMessage({
id: key
});
};
return <Component {...compProps} t={translate} locale={intl.locale} />;
}
WithTranslate.displayName = `withTranslate(${Component.displayName ||
Component.name}`;
WithTranslate.propTypes = {
intl: PropTypes.shape({
locale: PropTypes.string.isRequired,
formatMessage: PropTypes.func.isRequired
}).isRequired
};
return injectIntl(WithTranslate);
}
injectIntl from "react-intl" have typings
interface InjectedIntlProps {
intl: InjectedIntl;
}
interface InjectIntlConfig {
intlPropName?: string;
withRef?: boolean;
}
function injectIntl<P>(component: React.ComponentType<P & InjectedIntlProps>, options?: InjectIntlConfig):
React.ComponentClass<Pick<P, Exclude<keyof P, keyof InjectedIntlProps>>> & { WrappedComponent: React.ComponentType<P & InjectedIntlProps> };
I try to do this with
interface WithTranslateProps {
t: (key:string) => string;
locale: string;
}
export function withTranslate<T extends object>(Component:ComponentType<T & WithTranslateProps>):
ComponentType<T & WithTranslateProps> {
function WithTranslate<P>(props:P & InjectedIntlProps) {
const { intl, ...compProps } = props;
const translate = (key:string) => {
return intl.formatMessage({
id: key
});
};
return <Component {...compProps} t={translate} locale={intl.locale} />;
}
WithTranslate.displayName = `withTranslate(${Component.displayName ||
Component.name}`;
return injectIntl(WithTranslate);
}
It's not working.
TS2322: Type '{ t: (key: string) => string; locale: string; }' is not assignable to type 'T'.
TS2322: Type 'ComponentClass, any> & { WrappedComponent: ComponentType; }' is not assignable to type 'ComponentType'.
Type 'ComponentClass, any> & { WrappedComponent: ComponentType; }' is not assignable to type 'ComponentClass'.
Type 'Component, any, any>' is not assignable to type 'Component'.
Types of property 'props' are incompatible.
Type 'Readonly<{ children?: ReactNode; }> & Readonly>' is not assignable to type 'Readonly<{ children?: ReactNode; }> & Readonly'.
Type 'Readonly<{ children?: ReactNode; }> & Readonly>' is not assignable to type 'Readonly'.
Can anyone help me?

Typescript index signature any - only works with `any`?

I have an interface and a class :
export interface State {
arr : any[];
}
export const INITIAL_STATE: State = {
arr: []
};
This compiles.
Now I'm chaning the Interface to be like :
export interface State {
arr : any[];
[key: string]: any
}
And the class to be like :
export const INITIAL_STATE: State = {
arr: [] ,
'a':2
};
- Still compiles.
But now - If I want to be stricter in : [key: string]: any ---> [key: string]: number :
In other words :
export interface State {
arr : any[];
[key: string]: number
}
export const INITIAL_STATE: State = {
arr: [] ,
'a':2
};
I get an error :
Error:(7, 14) TS2322: Type '{ arr: undefined[]; 'a': number;
}' is not assignable to type 'State'. Property 'arr' is
incompatible with index signature.
Type 'undefined[]' is not assignable to type 'number'.
Question:
Why is that ?
I don't understand the logic behind this restriction.
What can I do to resolve it ?
The following interface:
export interface State {
arr : any[];
[key: string]: number
}
gives me the following error without even creating an object:
Property 'arr' of type 'any[]' is not assignable to string index type
'number'
This is because once you define [key: string]: number, TypeScript thinks all properties should be strings that map to a number. So you can't have an array unless you do:
export interface State {
[key: string]: number | any[]
}
Note that the reason the following interface worked:
export interface State {
arr : any[];
[key: string]: any
}
is that [key: string]: any tells TypeScript "map a string to anything", in other words, "turn off type checking for each string property". That is why you can have arr : any[]; without error.

Categories