泛型类型是否不在函数体内应用约束?

Does the generic type not apply constraint inside the body of a function?

我确定这是否可行,我是 TypeScript 的初学者,但我想做的是:

我有以下 type;

type Special<C> = {
    [Prop in keyof C]: C[Prop] extends Function | string ? C[Prop] : never;
}

只能有 stringFunction 类型的属性,因此,如果存在 numberArray 类型的 属性 等., 会产生错误:

class A {
    public msg: string = 'Hello!';
    public test() {}
}

const a: Special<A> = new A(); // Ok!

但是:

class B {
    public msg: string = 'Hello World!';
    public Run() {}
    public num: number = 123;
}

const b: Special<B> = new A(); // Error!, Type 'number' is not assignable to type 'never'.

如果我尝试在函数体内做同样的事情,类型检查不会完成:

type Class<ClassType = any, constructorParams = any> = {
    new (...agrs: Array<constructorParams>): ClassType;
};

class A {
    public msg: string = 'Hello!';
    public test() {}
    public num: number = 123;
}

const Testing = <T>(controller: Class<T>) => {
    const a: Special<typeof controller> = new controller(); // is Ok!???
};

Testing(A); // is Ok!???

我唯一能做到的就是像这样让类型检查工作:

class A {
    public msg: string = 'Hello!';
    public test() {}
    public num: number = 123;
}

const Testing = <T>(controller: Class<Special<T>>) => {
    const a = new controller(); 
};

Testing(A); // // Error!, Type 'number' is not assignable to type 'never'.

如何在 Testing 函数体内实现“Special”的类型检查?

我做错了什么吗?我是不是缺少了什么?

希望你能帮助我:)

根据您的评论,您似乎希望在 testing 的调用站点中引发错误。这实质上意味着您 必须 限制参数的类型 testing 可以接受。并且您应该以某种方式限制它,以便 [=69= 返回的实例] 构造函数,可分配给 Special.

好的,您已经提供的方位-

type Special<C> = {
    [Prop in keyof C]: C[Prop] extends Function | string ? C[Prop] : never;
}

这里是 class, 不能 正确通过-

class A {
    public msg: string = 'Hello!';
    public test() {}
    public num: number = 123;
}

这是一个类似的 class,应该 无误地通过-

class B {
    public msg: string = 'Hello!';
    public test() {}
}

好的,下面是您的 testing 函数的描述-

初步

它接受一个 class 构造函数作为它的参数。

声明

T为所述class构造函数构造的实例类型。

约束

T 必须可以分配给 Special<T>

实施

限制 T 可分配给 Special<T> 的方法是在函数中使用 T extends Special<T> 子句。结合上面的所有内容,你会得到-

function testing<T extends Special<T>>(controller: new (...args: any[]) => T) {
    const a: Special<T> = new controller();
};

没有什么特别的还没有讨论过。我摆脱了你的 Class 类型,因为我刚刚写了内联类型 - new (...args: any[]) => T。注意那里的 T 。那是实例类型。

现在您将在 testing(A) 上收到错误,但在 testing(B) 上不会。你得到的错误是-

Argument of type 'typeof A' is not assignable to parameter of type 'new (...args: any[]) => Special'. Construct signature return types 'A' and 'Special' are incompatible. The types of 'num' are incompatible between these types. Type 'number' is not assignable to type 'never'.

playground

上查看