声明包含对泛型函数的引用的变量的类型

时间:2017-09-10 21:49:29

标签: typescript typescript2.0

在本能中,而不是写作

function test<T>(param: T): T {
  return param;
}

test<string>("xxx");

我希望有一个类型声明,可以应用于分配给变量的箭头函数值。

type X<T> = (param: T) => T;
const test: X<T> = (param) => param; // <- ????
test<string>("XXX")

TS 2.5中是否可以采用非hacky方式? ......或者至少以一种黑客的方式?

背景:我正在尝试将现有的ES6代码迁移到Typescript。 ES6中的函数实现如下所示:

import * as React from "react";
import * as recompose from "recompose"

const formEnhancer = recompose.withContext(
  { form: React.PropTypes.any },
  function getChildContext(props) {
    const { value, errors, onChange } = props;
    return { form: { value, errors, onChange }};
  }
);

valueV类型,errorsIErrors<V>类型,onChangeChangeHandler<V>类型。

该函数的预期类型是

export type FormEnhancer<V> =
  recompose.InferableComponentEnhancerWithProps<{}, Props<V>>;

这是一个功能界面:

export interface InferableComponentEnhancerWithProps<TInjectedProps, TNeedsProps> {
  <P extends TInjectedProps>(component: Component<P>):
    React.ComponentType<Omit<P, keyof TInjectedProps> & TNeedsProps>
}

棘手的部分是我实际上找不到将这种类型声明添加到变量的方法。

写一些像

的东西
const formDecorator: FormEnhancer<V> = ...

导致立即失败,因为V未定义。

我能得到的最好的版本是将recompose.withContext包装到我自己的显式函数

function formEnhancer<V>(target: React.ComponentType) {
  return recompose.withContext<IContextProps<V>, Props<V>>(
    { form: React.PropTypes.any },
    function getChildContext(props) {
      const { value, errors, onChange } = props;
      return { form: { value, errors, onChange }};
    }
  )(target);
}

由于我仍然可以写

,因此无法解决问题
const raw = ({ foo }) => <input type="text" />;
const Wrapped = formEnhancer(raw);

这意味着TS无法推断目标的道具类型。 能够写出像

这样的东西
function formEnhancer<V>(target: React.ComponentType<P extends Props<V>>) {

会有所帮助。

2 个答案:

答案 0 :(得分:0)

这对我有用:

const test = (<T>(param: T) => param);

这将传递X<T>的定义,len(seq)是返回与第一个参数相同类型的任何函数。

答案 1 :(得分:-1)

我认为您正在寻找这个:

function formEnhancer<V, P extends Props<V>>(target: React.ComponentType<P>): void {
  ...
}

或更简单的例子:

class A<T> {
    a: T;
}
class B<T> {
    b: T;
}
function restricted1<P>(target: A<P>): void {
}

function restricted2<V, P extends B<V>>(target: A<P>): void {
}

let a1: A<number>;
let c: number;
let a2: A<B<number>>;

restricted1(a1); // succeeds
restricted1(c); // fails

restricted2(a1); // fails
restricted2(a2); // succeeds