Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Summary of magical TS type problems #1

Open
joe-sky opened this issue Mar 23, 2021 · 0 comments
Open

Summary of magical TS type problems #1

joe-sky opened this issue Mar 23, 2021 · 0 comments
Labels
documentation Improvements or additions to documentation

Comments

@joe-sky
Copy link
Owner

joe-sky commented Mar 23, 2021

I record some magical TS type problems here, and then study and analyze the causes. Some of them should be limitation of TS, you can refer to this issue.

The following are type errors and their current solutions:

1. Variables at root child of React.Fragment

✖️ Type error

const App = sfc({
  Component() {
    return { title: 'hello' };
  },

  render: ({ data }) => (
    <>{data.title}</>  // data.title is any
  )
})

✔️ Type passed

// You can do either of the following:
const App = sfc({
  Component() {
    return { title: 'hello' };
  },

  render: ({ data }) => (
    <React.Fragment>{data.title}</React.Fragment>
  )
})

const App2 = sfc({
  Component() {
    return { title: 'hello' };
  },

  render: ({ data }) => (
    <div>
      <>{data.title}</>
    </div>
  )
})

2. If styles is a function, you must use arrow functions to infer types correctly

✖️ Type error

const App = sfc({
  Component({ styles: { Container } }) {  // Container doesn't exist
    return (
      <Container>test</Container>
    );
  },

  styles() {
    return {
      Container: styled.section`
        color: #fff;
      `
    };
  }
});

✔️ Type passed

const App = sfc({
  Component({ styles: { Container } }) {
    return (
      <Container>test</Container>
    );
  },

  styles: () => ({
    Container: styled.section`
      color: #fff;
    `
  })
});

You can refer to similar problems in Vue 3.

3. In JSX(TSX is ok), static function must use the return statement to infer types correctly

✖️ Type error

const App = sfc({
  Component({ utils, constant: { LAST_NAME } }) {  // utils and LAST_NAME are both any
    ...
  },

  static: () => ({
    constant: {
      LAST_NAME: 'sky'
    },

    utils: {
      connectName: (firstName, lastName) => `${firstName}_${lastName}`
    }
  }),

  ...
});

✔️ Type passed

const App = sfc({
  Component({ utils, constant: { LAST_NAME } }) {
    ...
  },

  static: () => {
    return {  // need to explicitly use the return statement
      constant: {
        LAST_NAME: 'sky'
      },

      utils: {
        connectName: (firstName, lastName) => `${firstName}_${lastName}`
      }
    };
  },

  ...
})

4. In JSX(TSX is ok), when Component is arrow function, if there is any type in the function parameter during type inference, the whole data will be inferred as any

✖️ Type error

const App = sfc({
  Component: () => {
    return {
      onChange: e => console.log(e.target.value)
    };
  },

  render: ({ data }) => (
    <button onClick={data.onChange}>test</button>  // onChange is any
  )
})

✔️ Type passed

const App = sfc({
  Component() {  // need to use the object property function syntax
    return {
      onChange: e => console.log(e.target.value)
    };
  },

  render: ({ data }) => (
    <button onClick={data.onChange}>test</button>
  )
})

5. The data parameter of the render function doesn‘t support direct deconstruction

✖️ Type error

const App = sfc({
  Component() {
    return { title: 'hello' };
  },

  render: ({ data: { title } }) => (
    <div>{title}</div>  // title is any
  )
})

✔️ Type passed

const App = sfc({
  Component() {
    return { title: 'hello' };
  },

  render: ({ data }) => {
    const { title } = data;
    return <div>{title}</div>;
  }
})

This problem should be caused by the type circular reference problem of TS, there is no perfect solution for this problem. At present, my solution is to use extends to remove a layer of circular reference. For details, please refer to here.

6. Define functions in static function

✖️ Type error

const App = sfc({
  Component({ func, func2 }) {
    ...
  },

  static: () => {
    return {
      func: (a: string, b = false) => { // with default parameters
        ...
      },

      func2() {
        ...
      }
    };
  }
})

✔️ Type passed

const App = sfc({
  Component({ func, func2 }) {
    ...
  },

  static: () => {
    function func(a: string, b = false) {
      ...
    }

    return {
      func,

      func2: (a: string, b?: boolean) => { // must use arrow function
        ...
      }
    };
  }
})
@joe-sky joe-sky added question Further information is requested help wanted Extra attention is needed labels Mar 23, 2021
@joe-sky joe-sky pinned this issue Mar 24, 2021
@joe-sky joe-sky removed the help wanted Extra attention is needed label Mar 26, 2021
@joe-sky joe-sky added documentation Improvements or additions to documentation and removed question Further information is requested labels Jul 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant