当我在A
中声明泛型类a.js
并将其导出时,然后,我不知道如何在A
中声明类b.js
的变量
以下代码:
a.js
:
export let A = function<K extends { value: number }>(DEFAULT_NUMBER){
return class A<T> {
test(obj: T, num: number): K {
return obj.diff(DEFAULT_NUMBER, num);
};
};
}(
// DEFAULT_NUMBER
1000
);
b.js
import { A } from "a.js";
class B {
diff(): { value: number } {
// ...
}
};
let a: InstanceType<typeof A<B>> = new A();
a.test(new B(), 50);
下面的简单代码:
let A = class<T> {};
class B {};
let a: InstanceType<typeof A<B>>; // throw a syntax error
// or
let a: InstanceType<(typeof A)<B>>; // throw a syntax error
// or
let a: InstanceType<typeof (A<B>)>; // throw a syntax error
// or
let a: (InstanceType<typeof A>)<B>; // throw a syntax error
// or
let a: InstanceType<typeof A>; // correct, but the type of a is `A<unknown>`
我应该如何声明变量a
?
答案 0 :(得分:1)
我不认为这有语法。当然,没有语法可以获取具有特定类型参数的泛型函数的返回类型。
一种方法是通过虚拟函数:
let A = class<T> {};
class B {};
let aHelper = () => new A<B>();
let a: ReturnType<typeof aHelper>;
答案 1 :(得分:0)
据我了解,任何 .js 文件中都不应包含类型定义(例如value: number
)。相反,它们应该属于 .ts 文件(TypeScript,而不是JavaScript)。
在 TypeScript 中,如果您具有如下定义的通用类:
export class A<T extends { something: number }> {
useSomething(obj: T) {
console.log(obj.something)
}
}
然后可以像这样使用它:
class B {
something: number
}
const a = new A<B>()
a.useSomething(new B())
答案 2 :(得分:0)
这两天我一直在考虑这个问题,最后,我找到了答案,代码如下:
type ReplaceItemTypeOf<Target extends any[], NewType, OldType = unknown> = {
// for each item of the array
[Key in keyof Target]: (
// if the type is matched, return NewTypeNewType, otherwise return the origin type of the item value
OldType extends Target[Key] ? NewType : Target[Key]
);
};
type NonAnyType<T> = (T & 1 extends 1 ? 1 : 0) extends 1 ? T : never;
type InstanceTypeOfGenericRef<GenericRef extends new(...args: any) => any, Type> = {
// for each property
[Key in keyof InstanceType<GenericRef>]: (
// if the type is matched unknown type or empty object type
{} extends (
// if property is a method
InstanceType<GenericRef>[Key] extends (...args: any) => infer Result ?
// if type of Result is any return never, otherwise return the origin type of Result
NonAnyType<Result> :
// if type of the property value is any return never, otherwise return the origin type of the property value
NonAnyType<InstanceType<GenericRef>[Key]>
) ?
(
// if property is a method, and type has matched
InstanceType<GenericRef>[Key] extends (...args: infer Args) => infer Result ?
// return a new method interface which has replaced argument types
(...args: ReplaceItemTypeOf<Args, Type>) => Type :
// if not a method, return Type
Type
) :
(
// if property is a method and type has not matched
InstanceType<GenericRef>[Key] extends (...args: infer Args) => infer Result ?
// return a new method interface which has replaced argument types
(...args: ReplaceItemTypeOf<Args, Type>) => Result :
// return origin type of the property value
InstanceType<GenericRef>[Key]
)
);
};
let A = class A<T> {
set(value: T): T {
return value;
}
}
let a: InstanceTypeOfGenericRef<typeof A, string>;
a.set("123");