Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 请参阅当前函数的第一个参数类型_Typescript_Constructor_Typescript Generics - Fatal编程技术网

Typescript 请参阅当前函数的第一个参数类型

Typescript 请参阅当前函数的第一个参数类型,typescript,constructor,typescript-generics,Typescript,Constructor,Typescript Generics,所以我想做点什么,但我不知道怎么做 我想引用函数第一个参数的类型,并得到正确的推断类型。最好用一个例子来解释 type AllFood='草'|'肉'|'谷物'|'玉米'|'豆腐'; 类型Constructable=new(…args:any)=>T; //我有一个基本的抽象类,很多类都是建立在这个抽象类之上的 抽象类动物{ 公共食品:食品; 建造师(食物:食物){ 这就是食物; } } //我有很多这样的食物,它们只支持特定的食物子集 类DollyTheCow扩展了Animal{} //现在我

所以我想做点什么,但我不知道怎么做

我想引用函数第一个参数的类型,并得到正确的推断类型。最好用一个例子来解释

type AllFood='草'|'肉'|'谷物'|'玉米'|'豆腐';
类型Constructable=new(…args:any)=>T;
//我有一个基本的抽象类,很多类都是建立在这个抽象类之上的
抽象类动物{
公共食品:食品;
建造师(食物:食物){
这就是食物;
}
}
//我有很多这样的食物,它们只支持特定的食物子集
类DollyTheCow扩展了Animal{}
//现在我有了一个工厂函数,可以用它接收的参数来构建类
函数createClass(
SomeAnimalClass:可构造

我尝试了很多不同的选项,但基本上没有任何效果。我想避免在
createClass
函数中添加泛型,因为它是多余的。

也许这会起作用

您可以将食物类型添加到
Constructable
createClass
函数中,如下所示:

type AllFood = 'grass' | 'meat' | 'grain' | 'corn' | 'tofu';

type Constructable<T, TF extends AllFood> = new (food: TF, ...args: any) => T;

// I have a basic abstract class upon which a lot of class are built
abstract class Animal<Food extends AllFood = AllFood> { 
    public food: Food;

    constructor(food: Food) { 
        this.food = food;
    }
}

// I have a lot of like these that supports only a specific subset of food
class DollyTheCow extends Animal<'grass' | 'grain' | 'corn'> {}

// Now I have a factory function to build the classes with the params it receives
function createClass<T extends AllFood>(
SomeAnimalClass: Constructable<Animal<T>, T>, // <- The specific constructor
food: T // <- I want this to be typed according to the specific constructor just above, but it always fallsback to AllFood even when specifying a specific constructor that supports only a subset. 
) {
    const animal = new SomeAnimalClass(food);
}

createClass(DollyTheCow, 'meat'); // COMPILE ERROR
createClass(DollyTheCow, 'grass'); // This should be fine
type AllFood='草'|'肉'|'谷物'|'玉米'|'豆腐';
类型Constructable=new(食物:TF,…args:any)=>T;
//我有一个基本的抽象类,很多类都是建立在这个抽象类之上的
抽象类动物{
公共食品:食品;
建造师(食物:食物){
这就是食物;
}
}
//我有很多这样的食物,它们只支持特定的食物子集
类DollyTheCow扩展了Animal{}
//现在我有了一个工厂函数,可以用它接收的参数来构建类
函数createClass(

SomeAnimalClass:Constructable

如果没有泛型,您无法做到这一点。泛型允许
createClass
声明一个参数依赖于另一个参数。如果没有泛型,您无法比声明参数更具体地知道参数的类型

这意味着如果类型是
Animal
,则类型系统在没有运行时检查或泛型的情况下永远无法知道哪种动物

这就是说,一个微小的改变,以增加一个推断通用修复这一问题

function createClass<T extends Animal>(
    SomeAnimalClass: Constructable<T>,
    food: T['food']
) {
    const animal = new SomeAnimalClass(food);
}

createClass(DollyTheCow, 'meat'); // Error
函数createClass(
SomeAnimalClass:可构造,
食物:T[“食物”]
) {
const animal=新的某类动物(食物);
}
createClass(DollyTheCow,'meat');//错误

通用参数允许您将
DollyTheCow
转发到
Constructable
中,然后让您获取其食物


我不确定你对将
createClass
设置为泛型有什么担心,但我相当确定,如果不将其设置为泛型,就无法做到这一点。

谢谢你的提示,但正如我所说,我正试图避免使用泛型,因为它在我的应用程序中会变得非常冗余。我这里的示例是一个过度简化的示例,但实际上是这样的我必须为一个已经被使用了数百次的函数连续添加几个泛型。对不起,原来你的anwser也很好,但Alex Wayne的答案让我明白了!我同意Wayne的答案更好。如果你认为答案有用,你可以向上投票(点击向上箭头)如果泛型参数是推断的,那么使
createClass
泛型有什么多余的?您不必到处声明泛型,因为它可以通过参数类型推断。这似乎是我想要的,但我不完全理解为什么您可以调用类而不在这里传递泛型类型,因为泛型没有默认值。我认为
createClass(DollyTheCow,'meat')
会失败,我不得不使用
createClass(DollyTheCow,'meat')
。这就是为什么我认为它是多余的!泛型函数允许从参数推断其泛型类型。对于具有其他此类示例的泛型。