带有从不键入字段的Typescript接口
给定以下接口,什么是有效的可赋值值带有从不键入字段的Typescript接口,typescript,typescript3.8,Typescript,Typescript3.8,给定以下接口,什么是有效的可赋值值 interface A { x: number, y: never } 我所期望的是const a:a={x:1}可以工作,但它错误地说字段y是必需的。我一把y放进去,它就说这个值不能赋值给never 我的实际用例是这样的: interface Context<T extends MyRequest> { id: string; token: T extends AuthenticateRequest ? string : nev
interface A {
x: number,
y: never
}
我所期望的是const a:a={x:1}
可以工作,但它错误地说字段y
是必需的。我一把y
放进去,它就说这个值不能赋值给never
我的实际用例是这样的:
interface Context<T extends MyRequest> {
id: string;
token: T extends AuthenticateRequest ? string : never;
}
interface AuthenticatedRequest extends MyRequest { ... }
但出于显而易见的原因,这看起来很丑陋
知道我如何正确地执行此操作吗?您需要将类型设置为string或undefined。
never
类型在变量永远不会被赋值时使用,更详细
我认为这种方法应该能解决你的问题
接口A{
x:号码,,
y:字符串|未定义
}
Typenever
是空类型的表示。这意味着什么-没有属于这种类型的值,这意味着如果您使用它,您总是有编译错误
您需要的是更高级别的条件类型,请考虑:
type Context<T extends MyRequest> = T extends AuthenticateRequest ? {
id: string;
token: string;
} : { id: string };
type Context=T扩展AuthenticateRequest?{
id:字符串;
令牌:字符串;
}:{id:string};
这种方法消除了为
令牌设置未定义的负担。如果token
是必需的,那么对于T extends AuthenticateRequest
来说,它是一个字符串,如果不是,那么token
字段就不存在了。基于@Titian Cernicova Dragomir和@Maciej Sikora提到的要点,解决方法是我需要的类型定义的正确方法。接口
不能具有类型为从不
的字段,因为无法为其分配有效值,从而使接口无效
以下是我最终用于代码的内容:
type Context<T extends MyRequest> = Readonly<
{
logger: MyLogger;
timestamp?: number;
} & (T extends AuthenticatedRequest
? {
token: Token;
user: string;
}
: {}) &
(T extends GameRequest
? {
gameId: string;
}
: {}) &
(T extends ETagRequest
? {
etag: string;
}
: {}) &
(T extends UnParameterizedRequest
? {}
: {
params: Record<string, string | undefined>;
})
>;
type Context=Readonly<
{
记录器:MyLogger;
时间戳?:数字;
}&(T)扩展AuthenticatedRequest
? {
令牌:令牌;
用户:字符串;
}
: {}) &
(T)请求
? {
配子体:字符串;
}
: {}) &
(T)扩展eTaggrequest
? {
etag:字符串;
}
: {}) &
(T)扩展非参数化请求
? {}
: {
参数:记录;
})
>;
我认为您可能希望使用未定义的来代替从不
。具有从不成员的接口与从不本身一样好,因为该接口的任何值都不可能存在。您可以改为使用undefined
,但它不会使属性成为可选属性。我认为你目前的工作环境很好,你为什么不满意呢?有什么具体的原因吗,或者我更希望它是一个接口?其想法是在定义类型值时不必设置该字段,同时使接口看起来非常简单(我将添加更多的条件字段,这样它将开始看起来很混乱)。虽然据我所知,这里提到的解决方法是正确的,我没有其他选择……是的,这似乎是有道理的。我将添加更多具有不同T扩展另一个接口
条件的字段,这样会变得混乱,但看起来“解决方法”实际上是正确的方法。我不认为显式未定义设置是正确的方法,在T扩展AuthenticateRequest
的情况下不应考虑这种状态。如果我们进入-使不可能状态成为不可能,那么我所写的是正确的方法。我不确定你们的意思,因为我没有使用未定义。我把我的最终版本作为一个单独的答案。
type Context<T extends MyRequest> = Readonly<
{
logger: MyLogger;
timestamp?: number;
} & (T extends AuthenticatedRequest
? {
token: Token;
user: string;
}
: {}) &
(T extends GameRequest
? {
gameId: string;
}
: {}) &
(T extends ETagRequest
? {
etag: string;
}
: {}) &
(T extends UnParameterizedRequest
? {}
: {
params: Record<string, string | undefined>;
})
>;