Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to validate type "target.dataset" attribute of input tag in typescript

"dataset" attribute is always disallowed HTMLInputElement.

I searched the document of DOM types. There is no "data" or "dataset" anywhere.

Of course, it's possible to use "non-null" type likes below "variables key" in changeLoginValue.

export interface LoginForm {
    id: string;
    password: string;
    [key: string]: string;
}

export interface ILoginStore {
    loginValue: LoginForm;
    changeLoginValue(e: React.ChangeEvent<HTMLInputElement>): void;
}

class LoginStore implements ILoginStore {
    @observable loginValue: LoginForm = {
        id: '',
        password: '',
    }

    @action.bound changeLoginValue(e: React.ChangeEvent<HTMLInputElement>): void {
        const key = e.target.dataset.name!;
        this.loginValue[key] = e.target.value;
    }
}

It nicely works in application.

But it seems a some tricky way in typescript and the most important thing is that it always fail to compile in jest.

my test code is

import LoginStore from './loginStore';

describe('LoginStore', () => {
    it('change id and password in loginValue', () => {
        const event = {
            target: {
                dataset: {
                    name: 'id',
                },
                value: 'abcdef',
            },
          } as React.ChangeEvent<HTMLInputElement>;

        LoginStore.changeLoginValue(event);

        expect(LoginStore.loginValue.id).toBe('abcdef');
    })
})

It show typescript error when declare "const event":

Conversion of type '{ target: { dataset: { name: string; }; value: string; }; }' to type 'ChangeEvent' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

Type '{ target: { dataset: { name: string; }; value: string; }; }' is missing the following properties from type 'ChangeEvent': nativeEvent, currentTarget, bubbles, cancelable, and 10 more.ts(2352) ###

How to use "dataset" attribute? Do I have to make custom interface for this?

I'm using

"babel-jest": "^24.5.0",
"jest": "^24.5.0",
"typescript": "^3.4.1"
"ts-jest": "^24.0.1",
like image 570
Dylan Ju Avatar asked Oct 21 '25 03:10

Dylan Ju


1 Answers

event is a mock of a React.ChangeEvent.

It will never match the expected type (it's not going to implement nativeEvent, currentTarget, bubbles, cancelable, etc.).

For situations like these where you know your mock doesn't match the expected type and you want TypeScript to let it through anyway you can use the any type...

...to opt-out of type checking and let the values pass through compile-time checks.


const event: any = {  // <= use 'any' for the mock
  target: {
    dataset: {
      name: 'id',
    },
    value: 'abcdef',
  },
};
like image 122
Brian Adams Avatar answered Oct 23 '25 18:10

Brian Adams



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!