簡體   English   中英

反應測試中的 Linting 錯誤

[英]Linting errors in react testing

我正在自定義掛鈎上運行一些測試並且測試工作正常,盡管我在我的 localStorage TEST_VALUE 下遇到了很多錯誤。 在 localStorage 下,我收到以下信息:

Argument of type 'string | null' is not assignable to parameter of type 'string'.
  Type 'null' is not assignable to type 'string'.ts(2345)

我確定它來自我的鈎子:

import { useState, useEffect } from 'react';

export const useStateWithLocalStorage = (defaultValue: string, key: string) => {
  const [value, setValue] = useState(() => {
    const storedValues = localStorage.getItem(key);

    return storedValues !== null ? JSON.parse(storedValues) : defaultValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
};

但是不知道我將如何解決它,因為 !== null 需要在返回中才能使函數正常工作。

這是我的測試文件:

import { renderHook, act } from '@testing-library/react';
import { useStateWithLocalStorage } from '../UseStateWithLocalStorage';

describe('Test local storage', () => {
  test('should set local storage with default value', () => {
    const TEST_KEY: string = 'form';
    const TEST_VALUE = { name: 'matt' };
    renderHook(() => useStateWithLocalStorage(TEST_VALUE, TEST_KEY));

//^^ ERROR HERE UNDER TEST_VALUE 類型參數 '{ name: string; }' 不可分配給“字符串”類型的參數。

expect(JSON.parse(localStorage.getItem(TEST_KEY))).toEqual(TEST_VALUE);
      });

//^^ERROR HERE UNDER (localStorage.getItem(TEST_KEY) 'string | null' 類型的參數不可分配給'string' 類型的參數。'null' 類型不可分配給'string'.ts

      test('should update localStorage when state changes', () => {
        const TEST_KEY: string | null = 'form';
        const TEST_VALUE = { name: 'bill' };
    
        const { result } = renderHook(() => useStateWithLocalStorage(TEST_VALUE, TEST_KEY));
    
        // Pulls from result.current to update state
        const [, setValue] = result.current;
        const newValue = { name: 'john' };
    
        act(() => {
          setValue(newValue);
        });
    
        expect(JSON.parse(localStorage.getItem(TEST_KEY))).toEqual(newValue);
      });
    });

我在某處缺少類型嗎?

第二個錯誤

第二個更容易,所以讓我們從那里開始。

localStorage.getItem鍵入為:

Storage.getItem(key: string): string | null

這意味着它接受一個string參數,但你將它傳遞給string | null string | null

const TEST_KEY: string | null = 'form';
JSON.parse(localStorage.getItem(TEST_KEY))

這就是這個錯誤的含義:

'string | 類型的參數 null' 不能分配給“字符串”類型的參數。

類型“null”不可分配給類型“字符串”。(2345)

在這種情況下,您要刪除TEST_KEY的類型注釋,這將使其鍵入為string

但隨后getItem返回string | null string | nullJSON.parse接受一個string並且不能處理null 所以你有一個類似的問題。

你也需要提防這種情況。 但鑒於這只是一個測試,您不必提供有效的 JSON 字符串,因為它可能永遠不會執行。

這意味着您可以將上面的代碼段重寫為:

const TEST_KEY = 'form';
JSON.parse(localStorage.getItem(TEST_KEY) ?? 'error')

或者也可以使用后綴! 斷言該值不為空,但我不建議您使用它,因為這是一個壞習慣。

const TEST_KEY = 'form';
JSON.parse(localStorage.getItem(TEST_KEY)!)

第一個錯誤

然后,您將鈎子的第一個參數作為string鍵入:

export const useStateWithLocalStorage = (defaultValue: string, key: string) => {

然后你傳遞一個對象:

const TEST_VALUE = { name: 'matt' };
renderHook(() => useStateWithLocalStorage(TEST_VALUE, TEST_KEY));

這就是這個錯誤的含義:

'{ name: string; 類型的參數 }' 不可分配給“字符串”類型的參數。(2345)

要解決此問題,您必須正確鍵入useStateWithLocalStorage 您似乎希望能夠將復雜對象傳遞給useStateWithLocalStorage而不僅僅是字符串,因此我們需要更改函數參數的類型。

而且,無論狀態類型是什么,您都需要強大的類型安全性。 您可以將該參數類型設置為anyunknown ,但是您在輸入和輸出之間沒有強大的類型安全性。 所以要做到這一點,我相信你需要使函數generic

export const useStateWithLocalStorage = <T>(defaultValue: T, key: string) => {
  const [value, setValue] = useState<T>(() => {
    const storedValues = localStorage.getItem(key);

    return storedValues !== null ? JSON.parse(storedValues) : defaultValue;
  });

  useEffect(() => {
    localStorage.setItem(key, JSON.stringify(value));
  }, [key, value]);

  return [value, setValue];
};

現在defaultValue可以是任何未知類型,記住為T 然后我們將該類型傳遞給useState以使該狀態與defaultValue類型相同。 現在您的函數將返回[T, Dispatch<SetStateAction<T>>] ,它為您提供強類型的返回值。


看游樂場

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM