- 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/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: How to nest OR statements in JavaScript? 有没有办法做到这一点:
在 JavaScript 中有没有办法让一个变量总是等于一个变量?喜欢var1 = var2但是当var2更新,也是var1 . 例子 var var1 = document.getElementBy
我正在努力理解这代表什么 var1 = var2 == var3 我的猜测是这等同于: if (var2 == var3): var1 = var2 最佳答案 赋值 var1 = var2
这个问题已经有答案了: What does the PHP error message "Notice: Use of undefined constant" mean? (2 个回答) 已关闭 8
我在临时表中有几条记录,我想从每条记录中获取一个值并将其添加到一个变量中,例如 color | caption -------------------------------- re
如何将字符串转为变量(字符串变量--> $variable)? 或者用逗号分隔的变量列表然后转换为实际变量。 我有 2 个文件: 列名文件 行文件 我需要根据字符串匹配行文件中的整行,并根据列名文件命
我有一个我无法解决的基本 php 问题,我也想了解为什么! $upperValueCB = 10; $passNodeMatrixSource = 'CB'; $topValue= '$uppe
这可能吗? php $variable = $variable1 || $variable2? 如果 $variable1 为空则使用 $variable2 是否存在类似的东西? 最佳答案 PHP 5
在 Perl 5.20 中,for 循环似乎能够修改模块作用域的变量,但不能修改父作用域中的词法变量。 #!/usr/bin/env perl use strict; use warnings; ou
为什么这不起作用: var variable; variable = variable.concat(variable2); $('#lunk').append(variable) 我无法弄清楚这一点
根据我的理解,在32位机器上,指针的sizeof是32位(4字节),而在64位机器上,它是8字节。无论它们指向什么数据类型,它们都有固定的大小。我的计算机在 64 位上运行,但是当我打印包含 * 的大
例如: int a = 10; a += 1.5; 这运行得很完美,但是 a = a+1.5; 此作业表示类型不匹配:无法从 double 转换为 int。所以我的问题是:+= 运算符 和= 运算符
您好,我写了这个 MySQL 存储过程,但我一直收到这个语法错误 #1064 - You have an error in your SQL syntax; check the manual that
我试图在我的场景中显示特定的奖牌,这取决于你的高分是基于关卡的目标。 // Get Medal Colour if levelHighscore goalScore { sc
我必须维护相当古老的 Visual C++ 源代码的大型代码库。我发现代码如下: bIsOk = !!m_ptr->isOpen(some Parameters) bIsOk的数据类型是bool,is
我有一个从 MySQL 数据库中提取的动态产品列表。在 list 上有一个立即联系 按钮,我正在使用一个 jquery Modal 脚本,它会弹出一个表单。 我的问题是尝试将产品信息变量传递给该弹出窗
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
jQuery Core Style Guidelines建议两种不同的方法来检查变量是否已定义。 全局变量:typeof variable === "undefined" 局部变量:variable
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: “Variable” Variables in Javascript? 我想肯定有一种方法可以在 JavaScrip
在语句中使用多重赋值有什么优点或缺点吗?在简单的例子中 var1 = var2 = true; 赋值是从右到左的(我相信 C# 中的所有赋值都是如此,而且可能是 Java,尽管我没有检查后者)。但是,
我是一名优秀的程序员,十分优秀!