如何建立具有类型数组所有属性的类型?

时间:2019-08-05 08:07:10

标签: typescript typescript-generics

说我有两种类型(例如,我需要一些通用的东西)

class Login extends Component {

  state = {
    loggedIn: false,
    username: '',
    password: '',
  }

  loginHandler = (event) => {
    event.preventDefault();
    this.setState({ loggedIn: true, });
  }

  changeHandler = name => event => {
    let newState = { ...this.state, [name]: event.target.value };
    this.setState(newState);
  }

  render() {
    if (this.state.loggedIn) {
      this.props.loginHandler(this.state.loggedIn, this.state.username, this.state.password);
      console.log(this.props);
      this.props.history.push('/dashboard');
    }
    return (
      <Container component="main" maxWidth="xs">
        <CssBaseline />
        <div className={classes.paper}>
          <Avatar className={classes.avatar}>
            <LockOutlinedIcon />
          </Avatar>
          <Typography component="h1" variant="h5">
            Sign in
          </Typography>
          <form onSubmit={this.loginHandler} className={classes.form} noValidate>
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              id="standard-name"
              label="Name"
              name="name"
              autoComplete="name"
              autoFocus
              onChange={this.changeHandler('username')}
            />
            <TextField
              variant="outlined"
              margin="normal"
              required
              fullWidth
              name="password"
              label="Password"
              type="password"
              id="password"
              autoComplete="current-password"
              onChange={this.changeHandler('password')}
            />
            <FormControlLabel
              control={<Checkbox value="remember" color="primary" />}
              label="Remember me"
            />
            <Button
              type="submit"
              fullWidth
              variant="contained"
              color="primary"
              className={classes.submit}
            >
              Sign In
            </Button>
          </form>
        </div>
        <Box mt={5}>
        </Box>
      </Container>
    )
  }
}

我想写一个通用类型,让我做这样的事情

type TypeA = { propA: string};
type TypeB = { propB: number};

我尝试使用泛型和条件类型,但是我不知道如何在泛型类型数组上“迭代”。

2 个答案:

答案 0 :(得分:2)

诀窍是首先使用T[number]将所有数组元素“叠加”到一个元素上。 这样就给我们提供了所有类型的联合(例如TypeA | TypeB)。

由于您希望有一个交集类型(TypeA & TypeB),因此我们可以使用this answer中的漂亮技巧将该联合转换为交集。

完整示例:

type UnionToIntersection<U> =
    (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

type ArrayMerge<T extends Array<any>> = UnionToIntersection<T[number]>;

// Test it:
type TypeA = { propA: number };
type TypeB = { propB: string };

const ab: ArrayMerge<[TypeA, TypeB]> = {
    propA: 42,
    propB: "x",
};

ab.propA; // number
ab.propB; // string

playground中进行检查。

答案 1 :(得分:0)

您只需在Typescript中使用类型交集运算符&

type A = { propA: number };
type B = { propB: string };

type AB = A & B;

const ab: AB = {
    propA: 42,
    propB: "hello, world",
};

See on the playground