带有从不键入字段的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:字符串|未定义

}
Type
never
是空类型的表示。这意味着什么-没有属于这种类型的值,这意味着如果您使用它,您总是有编译错误

您需要的是更高级别的条件类型,请考虑:

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>;
        })
>;