我尝试修改常规用法的代码,用于声明生成(或手动编写声明)。代码是这样的:
function createClass<T>( data: T )
{
abstract class Internal<T2>
{
public constructor( arg: T2 )
{
console.log( data, arg );
}
protected abstract method( arg: T ): void;
}
return Internal;
}
问题是我应该指定函数结果的类型,但我不知道如何做到这一点 - 我尝试了不同的选项,但都没有。
加了:
这个小例子可能不完全清楚,所以我添加了出现问题的原始代码:
原始代码,我正试图变成一个包:https://gist.github.com/Avol-V/1af4748f4b0774a999311c92b6dc1631
您可以在那里找到small-redux
的代码:https://github.com/m18ru/small-redux/blob/master/src/createStore.ts
您可以在那里找到preact
的代码:https://github.com/developit/preact/blob/master/src/preact.d.ts
问题是我不想为创建的类的每次使用指定TState类型 - 它不能在创建的类上更改,因此它是不正确的。
加了:
所以,我没有找到任何解决方案,没有在创建的类的泛型中明确指定T
(除了T2
- class Internal<TInternal, T2>
)。我的结果代码如下:https://github.com/m18ru/preact-small-redux/blob/85c143e851b92c44861dc976ce6ef89bcda2c884/src/index.ts
如果你只想编写一个返回带泛型的类的函数,你可以像@baryo建议的那样(通过一些清理):
declare abstract class AbstractInternal<T>
{
public abstract method( arg: T ): void;
}
function createClass(): typeof AbstractInternal
{
abstract class Internal<T> implements AbstractInternal<T>
{
public abstract method( arg: T ): void;
}
return Internal;
}
const A = createClass();
class B extends A<string>
{
public method( arg: string ): string
{
return 'Hello ' + arg;
}
}
答案 0 :(得分:2)
您在函数内创建的所有内容都包含在其中,包括类型。因此,您至少需要定义类型。也许以下内容对您有所帮助:
interface IInternal<T> {
method(arg: T): void;
}
type InternalCtor<T> = new (param: T) => IInternal<T>;
function createClass<T>(data: T): InternalCtor<T>
{
abstract class Internal<T> implements IInternal<T>
{
public constructor( arg: T )
{
console.log( data, arg );
}
public abstract method( arg: T ): void;
}
return Internal as InternalCtor<T>;
}
class A extends createClass<number>(1) {
public method() {
console.log('hello');
}
}
const z = new A(2); // 1 2
编辑: 你提到你感兴趣的是泛型方法将返回一个泛型类 - 它对于打字变得有点棘手,但我们可以让Typescript本身推断我们需要的一切。
function createClass<T>(data: T)
{
// directly return a new class with a different generic type.
// notice that you can't return an abstract class.
return class Internal<U>
{
public constructor( arg: U )
{
console.log( data, arg );
}
public method(arg: T): void { console.log(arg); }
}
}
// first generic type (number) is for the function, then the second generic type (string) is for the returned class.
class A extends createClass<number>(1)<string> {
}
const z = new A('zzz'); // 1 zzz
z.method(2); // 2
编辑2: 它与你正在寻找的有点不同,但我认为更好的做法将是以下(类似于@Diullei所建议的):
abstract class AbstractInternal<T> {
public abstract method(arg: T): void;
}
type InternalCtor<T> = new (param: T) => AbstractInternal<T>;
function createClass<T, U>(data: T): InternalCtor<U> {
abstract class Internal<U> implements AbstractInternal<U>
{
public constructor(arg: T) {
console.log(data, arg);
}
public abstract method(arg: U): void;
}
return Internal as any as InternalCtor<U>;
}
class A extends createClass<number, string>(1) {
public method(arg: string) { // now I need to implement this to avoid a compilation error
console.log(`hello ${arg}`);
}
}
const z = new A('arg'); // 1 "arg""
z.method('arg2'); // "hello arg2""