diff --git a/tests/baselines/reference/user/formik.log b/tests/baselines/reference/user/formik.log new file mode 100644 index 0000000000000..30767a636c9ac --- /dev/null +++ b/tests/baselines/reference/user/formik.log @@ -0,0 +1,31 @@ +Exit Code: 1 +Standard output: +index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes, object>> & Readonly<{...'. + Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'Readonly>'. + Types of property 'onSubmit' are incompatible. + Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: object, formikActions: FormikActions) => void'. +index.tsx(26,7): error TS2322: Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes, object>> & Readonly<{...'. + Type '{ initialValues: { email: string; password: string; }; validate: (values: Values) => FormikErrors...' is not assignable to type 'Readonly>'. + Types of property 'onSubmit' are incompatible. + Type '(values: Values, { setSubmitting, setErrors }: FormikActions) => void' is not assignable to type '(values: object, formikActions: FormikActions) => void'. + Types of parameters 'values' and 'values' are incompatible. + Type 'object' is not assignable to type 'Values'. +index.tsx(32,13): error TS2322: Type '{}' is not assignable to type 'FormikErrors'. + Property 'email' is missing in type '{}'. +index.tsx(33,21): error TS2339: Property 'email' does not exist on type 'Values'. +index.tsx(36,68): error TS2339: Property 'email' does not exist on type 'Values'. +index.tsx(46,22): error TS2345: Argument of type 'Values' is not assignable to parameter of type 'MyData'. +index.tsx(47,11): error TS7006: Parameter 'user' implicitly has an 'any' type. +index.tsx(52,11): error TS7006: Parameter 'errors' implicitly has an 'any' type. +index.tsx(74,27): error TS2339: Property 'email' does not exist on type 'Values'. +index.tsx(76,20): error TS2339: Property 'email' does not exist on type 'FormikTouched'. +index.tsx(76,36): error TS2339: Property 'email' does not exist on type 'FormikErrors'. +index.tsx(76,58): error TS2339: Property 'email' does not exist on type 'FormikErrors'. +index.tsx(82,27): error TS2339: Property 'password' does not exist on type 'Values'. +index.tsx(84,20): error TS2339: Property 'password' does not exist on type 'FormikTouched'. +index.tsx(84,39): error TS2339: Property 'password' does not exist on type 'FormikErrors'. +index.tsx(84,64): error TS2339: Property 'password' does not exist on type 'FormikErrors'. + + + +Standard error: diff --git a/tests/cases/user/formik/index.tsx b/tests/cases/user/formik/index.tsx new file mode 100644 index 0000000000000..04e06cbd19326 --- /dev/null +++ b/tests/cases/user/formik/index.tsx @@ -0,0 +1,94 @@ +// Render Prop +import React from 'react'; +import { Formik, FormikErrors } from 'formik'; + +type MyData = {email: string, password: string}; +declare function LoginToMyApp(data: MyData): Promise<{user: string}>; +declare function transformMyApiErrors(o: any): FormikErrors; + +const Basic = () => ( +
+

My Form

+

This can be anywhere in your application

+ {/* + The benefit of the render prop approach is that you have full access to React's + state, props, and composition model. Thus there is no need to map outer props + to values...you can just set the initial values, and if they depend on props / state + then--boom--you can directly access to props / state. + + The render prop accepts your inner form component, which you can define separately or inline + totally up to you: + - `
...
}>` + - `` + - `{props =>
...
}
` (identical to as render, just written differently) + */} + { + // same as above, but feel free to move this into a class method now. + let errors: FormikErrors = {}; + if (!values.email) { + errors.email = 'Required'; + } else if ( + !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) + ) { + errors.email = 'Invalid email address'; + } + return errors; + }} + onSubmit={( + values, + { setSubmitting, setErrors /* setValues and other goodies */ } + ) => { + LoginToMyApp(values).then( + user => { + setSubmitting(false); + // do whatevs... + // props.updateUser(user) + }, + errors => { + setSubmitting(false); + // Maybe transform your API's errors into the same shape as Formik's + setErrors(transformMyApiErrors(errors)); + } + ); + }} + render={({ + values, + errors, + touched, + handleChange, + handleBlur, + handleSubmit, + isSubmitting, + }) => ( +
+ + {touched.email && errors.email &&
{errors.email}
} + + {touched.password && errors.password &&
{errors.password}
} + +
+ )} + /> +
+); + +export default Basic; \ No newline at end of file diff --git a/tests/cases/user/formik/package.json b/tests/cases/user/formik/package.json new file mode 100644 index 0000000000000..9641ca9aea668 --- /dev/null +++ b/tests/cases/user/formik/package.json @@ -0,0 +1,16 @@ +{ + "name": "formik", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "Apache-2.0", + "dependencies": { + "formik": "latest", + "@types/react": "latest", + "@types/prop-types": "latest" + } +} diff --git a/tests/cases/user/formik/tsconfig.json b/tests/cases/user/formik/tsconfig.json new file mode 100644 index 0000000000000..860e282bdf032 --- /dev/null +++ b/tests/cases/user/formik/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "jsx": "react", + "strict": true, + "esModuleInterop": true, + "noEmit": true, + "types": [] + }, + "files": [ + "index.tsx" + ] +} \ No newline at end of file