- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我试图在typescript中将类类型设置为泛型变量。使用泛型版本时显示编译错误。
export class A<T extends Al> { }
export class B extends A<Bl> { }
export class Al { }
export class Bl extends Al { }
show<T extends A<Al>>() {
let t: Type<T>; // "t = B" shows compile error but seem to work
// let t: Type<A<Al>>; // "t = B" shows no compile error and still works
t = B;
}
B extends A<Al>
和
T extends A<Al>
,通用版本
let t: Type<T>; t = B;
可以工作。相反,我必须使用
let t: Type<A<Al>>; t = B;
,我想知道我是否可以使用通用方法?
最佳答案
这里的示例代码违反了几个typescript最佳实践,因此我很难看到您的实际用例是什么:
您创建的所有类型都等效于空类型{}
,因此都是structurally equivalent to each other。这在实践中是很少见的。即使这里的代码只是一个玩具示例,我也怀疑您所指的A<T>
、B
、Al
和Bl
是否完全相同,而且即使您解决了问题中所述的问题,也可能会导致意外行为。
泛型类A<T>
does not depend structurally on its type parameter。因此,类型A<Al>
与A<Bl>
完全相同,而A<string>
与A<string>
完全相同(您是否认为string
不可能,因为Al
不扩展Al
?是的,因为show()
是空的…参见上一个要点)。再一次,我怀疑你的意思是这是真的。
因此,我将把您的示例代码修改为:
export class A<T extends Al> {
constructor(public t: T) {}
a: string = "a";
}
export class B extends A<Bl> {
constructor(t: Bl) {
super(t);
}
b: string = "b";
}
export class Al {
al: string = "al";
}
export class Bl extends Al {
bl: string = "bl";
}
T
函数在
T
中是通用的,但似乎不接受或返回任何依赖于
T
类型的参数。这很好,因为它只是示例代码,但是编译器无法从
show()
的用法推断
T
(请参阅
the documentation中的“类型参数推断”)。调用时,我们只需手动指定
show<T>()
。但在实际代码中,您可能希望
T
的调用签名依赖于
T
(或者您将从签名中完全删除
tGood
)。
function show<T extends A<Al>>() {
let tGood: Type<A<Al>> = B; // okay
let tBad: Type<T> = B; // error!
// 'B' is assignable to the constraint of type 'T',
// but 'T' could be instantiated with a different
// subtype of constraint 'A<Al>'.
}
Type<A<Al>>
是有效的。类型
A<Al>
表示“可分配给
B
的事物的构造函数”。值
Type<A<Al>>
是一个完全有效的
B
,因为它是一个构造函数,它生成
A<Al>
实例,这些实例被显式定义为扩展
X
。
Y
扩展
X
”、“
Y
可分配给
X
”、“
Y
比
X
窄(或与
Y
相同)”都表示(大致)相同的事情:如果您有一个
X
类型的值,则可以将其分配给
Y
类型的变量。扩展性/可分配性/狭窄性不是对称的。如果
Y
扩展
X
,则
string
扩展
string | number
并不一定正确。例如,考虑
const sn: string | number = "x"
可分配给
string | number
(例如,
string
可以),但
const s: string = Math.random()<0.5 ? "x" : 1
不可分配给
tBad
(例如,
T
是一个错误)。
T
。这是一个错误,因为
A<Al>
是某种泛型,我们只知道
A<Al>
扩展了
A<Al>
。它不一定等于
T
。事实上,可能是一个严格意义上较窄的
A<Al>
亚型(也就是说,
A<Al>
extends
T
并不意味着
B
extends
Type<A<Al>>
)。因此我们不能将
B
分配给
T
,因为
'T' could be instantiated with a different subtype of constraint 'A<Al>'
的实例可能不会成为
C
的实例。(错误消息明确指出:
c
)
export class C extends A<Al> {
constructor(t: Al) {
super(t);
}
c: string = "c";
}
show<C>(); // no error, but B does not create instances of C
B
的一个实例有一个名为
c
的字符串属性。但是
show<C>()
构造函数不生成具有
T
属性的实例。我可以调用
C
,将
C
指定为
A<Al>
。这是可以接受的,因为
let t: Type<T> = B
扩展了
let t: Type<C> = B
,但是…在实现的内部,
tGood
实际上是在说
Type<T>
,这是不正确的。因此产生了错误。
B
。完全删除泛型可以解决这个问题。如果需要继续使用泛型,则可能需要传入这些泛型类型的参数。也就是说,像这样:
function showMaybe<T extends A<Al>>(ctor: Type<T>) {
let tFine: Type<T> = ctor;
}
showUnsafe<C>()
你必须通过一个…你不能只希望
tUnsafe
是一个。再说一次,我不知道上面的方法对你是否有效,但像这样的方法可能是可行的。
function showUnsafe<T extends A<Al>>() {
let tUnsafe: Type<T> = B as any as Type<T>; // unsafe assertion
}
C
,根据您对
B
所做的操作,您可能最终会对编译器撒谎,认为构造的实例是
关于angular - 将类类型分配给泛型变量时,Typescript编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56933110/
是否有任何库或框架旨在促进从另一种成熟的编程语言中构建项目? 在 C++、java 等编程语言中指定逻辑、集合和复杂规则非常容易,但在 Makefile 中完成这些事情似乎是一场艰苦的战斗。我还没有深
我有这段代码可以用 clang 编译得很好(即使使用 -Weverything),但是 gcc 会发出错误。 #include #include #include using namespace
我有以下 block 头文件 BKE_mesh.h: /* Connectivity data */ typedef struct IndexNode { struct IndexNode *
我在我的一个项目中遇到了一个奇怪的问题。我的代码库依赖于一个外部库,其中包含一个名为 Dataset 的类. Dataset类私有(private)继承自 std::vector (其中 Sample
当使用 gcc、g++ 或 make 在终端中编译一个小型 C 或 C++ 项目时,我收到以下错误: /tmp/ccG1caGi.o: In function `main': main.c:(.tex
我正在尝试从 CVS 为 Windows 上的 Emacs 23.1.50 编译 CEDET,但在“第 6 步:打开 EDE...”时出现错误:“defvar:作为变量的符号值是无效的:cedet-m
我正在(重新)学习编程,我从 C 开始。我的 IDE(如果我可以这么说)是 Windows7 上的 cygwin(32 位)和 Visual-Studio 2010。我总是编译我用 gcc (cygw
我喜欢在模板类中使用本地类来执行类似“static if”的构造。但是我遇到了 gcc 4.8 不想编译我的代码的问题。但是 4.7 可以。 这个例子: #include #include #in
我有一个项目,必须仅使用 java 1.4 进行编译。但我计划使用mockito 编写一些单元测试。我想要一种在 pom 中指定的方法,以便 src/main/java 使用 jdk 1.4 编译,但
我想了解 PHP 编译过程是如何工作的。 假设我有一个名为funcs.php 的文件并且这个文件有三个函数,如果我include 或require 它,所有的在文件加载期间编译三个函数?或者源代码会被
编译工具链 我们写程序的时候用的都是集成开发环境 (IDE: Integrated Development Environment),集成开发环境可以极大地方便我们程序员编写程序,但是配置起来
当我编写一些 Scala 代码时,在尝试编译代码时收到一条奇怪的错误消息。我将代码分解为一个更简单的代码(从语义的角度来看这完全没有意义,但仍然显示了错误)。 scala> :paste // Ent
我正在编译一个 SCSS 文件,它似乎删除了我的评论。我可以使用什么命令来保留所有评论? >SASS input.scss output.css 我在 SCSS 中看到两种类型的注释。 // Comm
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
当您编译 grails war 时,我知道 .groovy 代码被编译为字节码类文件,但我不明白容器(例如 tomcat)如何在请求 GSP 时知道如何编译它们。容器了解 GSP 吗?安装在服务器上的
我正在努力将多个文件编译成一个通用程序。我收到一个错误: undefined reference to 'pi' 这是我的代码和 Makefile 的框架。我做错了什么?谢谢! 文件:calcPi.c
我尝试使用 LD_PRELOAD 来 Hook sprintf function ,所以我将打印到缓冲区的结果: #define _GNU_SOURCE #include #include int
我正在寻找最简单的方法来自动将 CoffeeScript 重新编译为 JS。 阅读documentation但仍然很难得到我想要的东西。 我需要它来监视文件夹 src/ 中的任何 *.coffee 文
我想使用定制waveformjs 。我发现this on SO但是,我不知道如何编译/安装波形来开始。我从 GitHub 克隆它并进行了更改,但是我不知道如何将其转换为 .js 文件。 最佳答案 为了
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我是一名优秀的程序员,十分优秀!