javascript - 将泛型类型传递给打字稿中的函数
问题描述
考虑示例:
interface A {
foo: string;
}
interface B {
foo: string;
}
function a<T>() {
function b(arg: T) {
return arg.foo;
^^^^^^ Property 'foo' does not exist on type 'T'.
}
return b;
}
a<A>();
a<B>();
如何使它工作,所以我不必硬核这样的类型:
function b(arg: A | B)
所以我将能够将类型作为泛型传递,所以如果有 5 种甚至更多不同的类型,我就不必像A | B | C | D | E...
泛型那样做吗?
解决方案
为了让您能够访问arg.foo
,编译器必须确信,至少,arg
实际上可能有一个名为 的属性foo
。所以 的类型arg
必须可以分配给类似的东西{foo?: unknown}
,其中foo
是一个可选属性,属性的unknown
类型是类型。
从您的示例中不清楚您是否要制作比这更严格的东西(比如说它肯定有一个名为 的属性foo
,或者该属性的值必须是 a string
)。现在,我只假设您想要arg.foo
无错误地访问。
如果您使用泛型类型参数T
作为 的类型arg
,则T
必须将其限制为可分配给 的东西{foo?: unknown}
。
例如:
function a<T extends { foo?: unknown }>() {
function b(arg: T) {
return arg.foo; // okay, no error
}
return b;
}
T extends A | B | C | ...
假设所有的A
, B
, C
, etc... 类型本身都可以分配给{ foo?: unknown }
. 您的给定A
和B
类型是可分配的,因此以下工作:
a<A>();
a<B>();
请注意,示例中的您的A
和B
类型实际上是相同的。TypeScript 的类型系统是结构化的。因为类型A
和结构B
相同,所以它们是相同的类型。有两个声明和两个不同的名称并不重要:
let aVal: A = { foo: "a" };
let bVal: B = { foo: "b" };
aVal = bVal; // okay
bVal = aVal; // okay
因此,如果您希望编译器强制执行存在并且是; ,那么编写T extends A
会很好。它不会停止工作。结构类型系统使您不必预测所有可能的命名类型:foo
string
B
function a2<T extends A>() {
function b(arg: T) {
return arg.foo.toUpperCase();
}
return b;
}
a2<A>(); // okay
a2<B>(); // okay
interface C {
foo: string;
bar: number;
}
a2<C>(); // okay
a2<Date>(); // error
// ~~~~
// Property 'foo' is missing in type 'Date' but required in type 'A'.
如果您关心 name 的“硬编码” ,您可以使用像inA
这样的匿名类型,但从类型系统的角度来看,这并没有太大变化,因为和是相同的类型。{foo: string}
T extends {foo: string}
A
{foo: string}
推荐阅读
- python - 使用 wxpython 和 cefpython3 禁用 windows 边框
- java - java.lang.ClassCastException: android.widget.LinearLayout$LayoutParams 不能转换为 android.support.constraint.ConstraintLayout$LayoutParams
- mysql - 任何适用于 MySQL 的功能性 Jupyter 内核?
- javascript - 在游戏循环中处理键盘交互 - javascript
- python-3.x - 解析xml文件pandas df
- matlab - 如何在 MATLAB 中绘制相量
- flutter - 如何在颤动中将国家拨号代码添加到 TextEditingController
- html - 如何将数据从一个 React.js 文件传递到另一个文件?
- firebase-authentication - 使用 Firebase UID 作为用户的数据存储区密钥名称是不是一个坏主意?
- c# - 如何在 xunit 中测试是否引发了 Event?