- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这些是我的类型:
type Action<T> = T extends undefined ? {
type: string;
} : {
type: string;
payload: T;
}
type ApiResponse<T> = {
ok: false;
error: string;
} | {
ok: true;
data: T;
};
我已经定义了这个函数:
function handleApiResponse<T>(apiResponse: ApiResponse<T>) {
const a: Action<ApiResponse<T>> = {
type: "response",
payload: apiResponse,
}
}
问题是a
有一个错误,因为 Action
中的条件类型分布在ApiResponse
.
我需要从 Action<T>
得到什么是一种字面意思的类型,即有两种情况:
Action<T>
的类型参数未定义,在这种情况下 Action<undefined>
= { type: string }
Action<T>
的类型参数是别的什么,在这种情况下Action<T>
= { type: string, payload: T }
但是当 T
时这不起作用是联合类型,因为分布式条件类型。
我怎样才能定义一个这样的类型,即使在 T
时也能正常工作?是工会吗?
最佳答案
如您所述,您对 Action<T>
的定义是 distributive conditional type , 其中unions在T
被分成各自的成员(例如 B | C | D
),通过 Action<T>
传递,并将结果放回新的联合中(例如 Action<B> | Action<C> | Action<D>
)。这通常是人们希望从他们的条件类型中得到的行为,但这不是您在这里想要的;也就是说,您不小心使用了分布式条件类型。
TTT extends UUU ? VVV : WWW
形式的条件类型仅当类型 TTT
时才是分布式的你正在检查的是裸generic 类型参数,例如 T
在你对 Action<T>
的定义中.如果它是某种特定类型(如 string
或 Date
),它将不是分布式的。如果它是涉及类型参数的更复杂的表达式(如 {x: T}
),它就不是分布式的。我有时会引用后一种想法,您可以在其中采用“裸”类型参数 T
并像{x: T}
一样对它做点什么,作为“服装”类型参数。
所以你有 T extends undefined
,这是分配的:
type Action<T> = T extends undefined ? ... : ...
如果你想关闭它,你需要重新措辞检查,这样 T
穿上衣服但具有相同的行为(因此当且仅当 T
扩展 undefined
时检查成功)。最简单的方法是在 extends
的两边都穿上衣服子句是一个元素 tuple type ), 所以 T
变成 [T]
和 undefined
变成 [undefined]
:
type Action<T> = [T] extends [undefined] ? ... : ...
然后你的代码就可以工作了:
function handleApiResponse<T>(apiResponse: ApiResponse<T>) {
const a: Action<ApiResponse<T>> = {
type: "response",
payload: apiResponse,
} // okay
}
请注意,TypeScript 将元组和数组视为 covariant在它们的元素类型中,这意味着 Array<X> extends Array<Y>
或 [X] extends [Y]
当且仅当 X extends Y
.这在技术上是不安全的(请参阅 this question 及其答案以获取更多信息)但非常方便。
这是您可以使用的一般规则:如果您有 TTT extends UUU ? VVV : WWW
而且它是意外分布的,你可以通过写 [TTT] extends [UUU] ? VVV : WWW
来关闭它.这在 documentation for distributive conditional types 的底部提到,虽然它只是说“做这个”而不是它为什么有效。方括号可能看起来像是为条件类型设计的某种特殊语法……但事实并非如此。它只是使用现有的单元素元组语法,它恰好可以做我们想做的事,而不需要太多的字符。
关于typescript - 如何避免分配条件类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70789029/
我已经写了并且 npm 发布了这个:https://github.com/justin-calleja/pkg-dependents 现在我正在用 Typescript 编写这个包:https://g
我有一个函数,我想在 TypeScript 中模拟它以进行测试。在我的测试中,我只关心 json和 status .但是,当使用 Jest 的 jest.spyOn 时我的模拟函数的类型设置为返回 h
我正在使用一个库 (Axios),它的包中包含 Typescript 声明。 我想声明一个将 AxiosResponse(在库的 .d.ts 文件中声明)作为参数的函数。我有以下内容: functio
我是 Typescript 的新手。我想使用 将一个 Typescript 文件加载到另一个 Typescript 文件中标签。 我做了一些事情,但它不起作用!请帮助我。 first.ts: imp
为什么我会收到下面屏幕截图中显示的错误? Atom 说我的 tsconfig.json“项目文件包含无效选项”用于 allowJs、buildOnSave 和 compileOnSave。 但是应该允
所以我正在创建一个 TypeScript 库,我可以轻松地将所有生成的 JS 文件编译成一个文件。有没有办法将所有 .ts 和 .d.ts 编译成一个 .ts 文件? 除了支持 JS 的版本(较少的智
Microsoft Research 提供了一种名为Safer TypeScript 的新 TypeScript 编译器变体: http://research.microsoft.com/en-us/
我需要这个来在单个文件中分发 TypeScript 中的库。有没有办法将多个 typescript 文件合并到(一个js文件+一个 typescript 定义)文件中? 最佳答案 要创建一个库,您可以
用例:我想知道一个函数在 typescript 中执行需要多少时间。我想为此目的使用装饰器。我希望装饰器应该返回时间以便(我可以进一步使用它),而不仅仅是打印它。 例如: export functio
我想检查一个类型是否可以为 null,以及它是否具有值的条件类型。 我尝试实现 type IsNullable = T extends null ? true : false; 但是好像不行 type
我的问题是基于这个 question and answer 假设我们有下一个代码: const myFn = (p: { a: (n: number) => T, b: (o: T) => v
我知道双重否定前缀,我知道 TypeScript 的单后缀(非空断言)。 但是这个双后缀感叹号是什么? /.*验证码为(\d{6}).*/.exec(email.body!!)!![1] 取自here
我正在使用以下文件结构在 Webstorm 中开发一个项目 | src | ... | many files | types | SomeInterface |
在 TypeScript 类中,可以为属性声明类型,例如: class className { property: string; }; 如何在对象字面量中声明属性的类型? 我试过下面的代码,但它
我正在寻找一种在不丢失推断类型信息的情况下将 TypeScript 中的文字值限制为特定类型的好方法。 让我们考虑一个类型Named,它保证有一个名字。 type Named = { name:
在 TypeScript 中,我想创建一个联合类型来表示属于一个或多个不同类型的值,类似于 oneOf在 OpenAPI或 JSON Schema .根据a previous answer on a
type Func = (foo:string) => void // function expression const myFunctionExpression:Func = function(f
假设我有一个联合类型,我正在使用类似 reducer 的 API 调用模式,看起来像这样: type Action = { request: { action: "create
我在 typescript 中有以下去抖功能: export function debounce( callback: (...args: any[]) => void, wait: numb
在 Vue3 的 defineComponent 函数中,第一个泛型参数是 Props,所以我在这里使用 Typescript 接口(interface)提供我的 props 类型。喜欢: expor
我是一名优秀的程序员,十分优秀!