使用参数化的TypeScript类作为类型参数

时间:2018-12-15 04:16:59

标签: typescript templates generics

最近的TypeScript(3.1)具有出色的类型推断功能。它发现通过严格的类型检查能够做到这一点非常有用:

class Foo {
  constructor(a: number, b: string) {}
}

function create<T extends new(...args: any[]) => any>(
    cls: T, ...args: ConstructorParameters<T>): InstanceType<T> {
  return new cls(...args);
}

let a: Foo = create(Foo, 18, "a");   // <-- yay, fully typechecked

但是当我的班级是通用的(参数化的)时,我找不到任何方法可以做到这一点:

class Bar<T> {
  constructor(a: T, b: string) {}
}

let b = create(Bar, "asdf", "a");          // <--- not typechecked
let c = create(Bar<number>, 20, "a");              // <--- error
let d = create<typeof Bar<number>>(Bar, 20, "a");  // <--- error

我该怎么办?

1 个答案:

答案 0 :(得分:1)

问题是,private static final int INSIDE_QT = 1; private static final int OUTSIDE_QT = 0; public String[] parseLine(char delimiter, char quote, char quoteEscape, char charToEscapeQuoteEscaping, String logLine) { char[] line = logLine.toCharArray(); List<String> strList = new ArrayList<>(); int state = OUTSIDE_QT; char lastChar = '\0'; StringBuffer currentToken = new StringBuffer(); for (int i = 0; i < line.length; i++) { if (state == OUTSIDE_QT) { if (line[i] == delimiter) { strList.add(currentToken.toString()); currentToken.setLength(0); } else if (line[i] == quote) { if (lastChar == quoteEscape) { currentToken.deleteCharAt(currentToken.length() - 1); currentToken.append(line[i]); } else { if (removeQuotes == false) { currentToken.append(line[i]); } state = INSIDE_QT; } } else if (line[i] == quoteEscape) { if (lastChar == charToEscapeQuoteEscaping) { currentToken.deleteCharAt(currentToken.length() - 1); currentToken.append(line[i]); continue; } else { currentToken.append(line[i]); } } else { currentToken.append(line[i]); } } else if (state == INSIDE_QT) { if (line[i] == quote) { if (lastChar != quoteEscape) { if (removeQuotes == false) { currentToken.append(line[i]); } if (currentToken.length() == 0) { currentToken.append('\0'); } state = OUTSIDE_QT; } else { currentToken.append(line[i]); } } else if (line[i] == quoteEscape) { if (lastChar == charToEscapeQuoteEscaping) { currentToken.deleteCharAt(currentToken.length() - 1); currentToken.append(line[i]); continue; } else { currentToken.append(line[i]); } } else { currentToken.append(line[i]); } } lastChar = line[i]; } if (lastChar == delimiter) { strList.add(""); } if (currentToken.length() > 0) { strList.add(currentToken.toString()); } return strList.toArray(new String[strList.size()]); } 中的通用参数T似乎仅适用于Bar<T>的实例部分,而不适用于静态部分,尽管在Bar中使用了{构造函数签名(构造函数属于静态部分)。

解决方法是具有定义静态部件as suggested in this answer的显式接口,并使用“高阶”函数T代替类:

Bar<T>()