1

我正在 React 中尝试并发模式和悬念,当我尝试从父组件钻取一些模拟数据到子组件时遇到类型错误,因为我的 promise 包装器本身并不知道正在读取的类型。我收到的错误消息是:

TS2739:类型'{数据:任何;}' 缺少“MockData”类型的以下属性:标题、名称、地址、城市

我如何让我的承诺包装器知道返回给它的类型而不明确说明,export const promiseWrapper = (promise: Promise<MockData>): PromiseWrapper => {...因为我想将此承诺包装器用于可能返回其他接口的其他提取?谢谢!

示例组件.tsx:

import * as React from 'react';
import api, { MockData } from 'api/api';

const resource = api.getMockData();

const SampleComponent: React.FC = () => {
  const mockData = resource.mockData.read();
  return (
    <ChildComponent mockData={mockData} /> // type error received here
  );
};

interface ChildProps {
  mockData: MockData;
}

const ChildComponent: React.FC<ChildProps> = ({ mockData }) => (
  <div>
    <h1>{mockData.title}</h1>
    <h1>{mockData.name}</h1>
    <h1>{mockData.address}</h1>
    <h1>{mockData.city}</h1>
  </div>
);

api.ts:

import { PromiseWrapper, promiseWrapper } from './promiseWrapper';

export interface Resource {
  [key: string]: PromiseWrapper;
}

export interface MockData {
  title: string;
  name: string;
  address: string;
  city: string;
}

const mockData = {
  title: 'this is a title',
  name: 'John Smith',
  address: '102 Street',
  city: 'Pittsburgh',
};

const mockDataPromise = (): Promise<{ data: MockData }> => new Promise((resolve) => {
  setTimeout(() => {
    resolve({
      data: mockData,
    });
  }, 1000);
});

const getMockData = (): Resource => {
  const getMockDataPromise = mockDataPromise();
  return {
    mockData: promiseWrapper(getMockDataPromise),
  };
};

export default {
  getMockData,
};

promiseWrapper.ts:

export interface PromiseWrapper {
  read(): {
    data: any;
  };
}

export const promiseWrapper = (promise: Promise<any>): PromiseWrapper => {
  let status = 'pending';
  let result: object;
  const suspender = promise.then(
    (r) => {
      status = 'success';
      result = r;
    },
    (e) => {
      status = 'error';
      result = e;
    },
  );
  return {
    // @ts-ignore
    // eslint-disable-next-line consistent-return
    read() {
      if (status === 'pending') {
        throw suspender;
      } else if (status === 'error') {
        throw result;
      } else if (status === 'success') {
        return result;
      }
    },
  };
};
4

1 回答 1

1
  export interface PromiseWrapper<T> {
    read(): { data: T }
  }

  export function promiseWrapper<T>(promise: Promise<{ data: T }>): PromiseWrapper<T> {
    let status = 'pending'
    let result: { data: T }
    /* rest of the function remains unchanged ... */
  }
于 2019-11-26T17:10:41.157 回答