打字稿:是否可以为导出类型中的一个键设置状态?

Typescript: Is it possible to setState for only one key in exported type?

我决定尝试在我的 React 应用程序中学习 Typescript,但我遇到了第一个错误,我无法弄清楚或找到答案。

是否可以只访问导出类型中的一个特定键并更改其值?

所以我导出我的类型是这样的:

export type MyFirstTestType = {
    id: number;
    name: string;
    price: number;
    object1: {
        name: string;
        price: number;
},
    object2: {
        name: string;
        price: number;
},

然后我从外部获取值 API

const getTestItems = async (): Promise<MyFirstTestType[]> =>
    await (await fetch('apiEndpoint')).json();

在经典 JS 中,我会为价格创建新状态

 const [itemPrice, setItemPrice] = React.useState(data.price)

然后使用 onClick 函数轻松更新状态。是否可以使用 TypeScript 实现类似的功能?所以我只能从 MyFirstTestType?

更新 price

我试过类似的东西:

const [price, setPrice] = React.useState<MyFirstTestType>({price: 100}); 

但是这个抛出错误 -> Type '{ price: number; }' 缺少 MyFirstTestType (id, name,...)

中的其余属性

首先你应该使用接口而不是类型

您可以为扩展原始类型的 setState 类型使用另一种类型

export interface MyFirstTestType {
  id: number;
  name: string;
  price: number;
  object1: {
    name: string;
    price: number;
  };
  object2: {
    name: string;
    price: number;
  };
}
export interface MyFirstTestTypeState extends Partial<MyFirstTestType> {
  name?: string;
  price: number;
  object1?: {
    name: string;
    price: number;
  };
  object2?: {
    name: string;
    price: number;
  };
}

在这种情况下,id 和其他仅对状态是可选的,但对于您的请求,您可以使用 id 和其他不是可选的,您仍然可以看到 MyFirstTestType 属性并使用他们唯一的区别是你现在可以更新任何你想要的 属性

现在导入,然后进入你的使用状态

  const [price, setPrice] = useState<MyFirstTestTypeState>({price:2});

这是沙盒示例
https://codesandbox.io/s/cranky-hooks-zwisw?file=/src/App.tsx:154-224

你问题中的例子具有误导性。

JS: const [itemPrice, setItemPrice] = React.useState(data.price)

TS: const [price, setPrice] = React.useState<MyFirstTestType>({price: 100});

在 JS 示例中,您使用 data.price 中的值初始化 itemPrice(不清楚 data 的来源)。请注意,虽然 setItemPrice 会更新您的 itemPrice 变量,但它不会像您想象的那样更新 data 对象上的值。但是在 TS 示例中,您正在做一些不同的事情:您正在使用一个全新的对象初始化 price

现在的重点是:price 会保持什么样的价值?

如果这是一个简单的价格(就像在 JS 示例中那样),那么您的类型声明是错误的,因为您将该值声明为 MyFirstTestType

如果它确实持有类型 MyFirstTestType 的值,那么您一定要传递一个有效的 MyFirstTestType 实例作为初始值(或 undefined)。有效的 MyFirstTestType 实例的外观取决于您的类型声明。

但请注意,无论是在 JS 还是在 TS 中,您都应该将您的状态视为不可变的:这里唯一的区别是类型检查。