[英]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 | null
和JSON.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
而不僅僅是字符串,因此我們需要更改函數參數的類型。
而且,無論狀態類型是什么,您都需要強大的類型安全性。 您可以將該參數類型設置為any
或unknown
,但是您在輸入和輸出之間沒有強大的類型安全性。 所以要做到這一點,我相信你需要使函數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.