Object 在TypeScript中将对象强制转换为接口

Object 在TypeScript中将对象强制转换为接口,object,typescript,interface,casting,Object,Typescript,Interface,Casting,我试图在我的代码中从express中的请求主体(使用主体解析器中间件)转换到接口,但它没有强制执行类型安全 这是我的界面: export interface IToDoDto { description: string; status: boolean; }; 这是我试着做演员的代码: @Post() addToDo(@Response() res, @Request() req) { const toDo: IToDoDto = <IToDoDto> req.body

我试图在我的代码中从express中的请求主体(使用主体解析器中间件)转换到接口,但它没有强制执行类型安全

这是我的界面:

export interface IToDoDto {
  description: string;
  status: boolean;
};
这是我试着做演员的代码:

@Post()
addToDo(@Response() res, @Request() req) {
  const toDo: IToDoDto = <IToDoDto> req.body; // <<< cast here
  this.toDoService.addToDo(toDo);
  return res.status(HttpStatus.CREATED).end();
}
我可以传递任何参数,即使是与接口定义不匹配的参数,这段代码也可以正常工作。如果无法从响应体转换到接口,我希望在运行时抛出异常,如Java或C#


我已经读到,在类型脚本中不存在强制转换,只有类型断言,因此它只会告诉编译器对象的类型是
x
,所以。。。我错了吗?实施和确保类型安全的正确方法是什么

javascript中没有强制转换,因此如果“强制转换失败”,则无法进行强制转换。
Typescript,但这仅用于编译时间,您可以这样做:

const toDo = <IToDoDto> req.body;
// or
const toDo = req.body as IToDoDto;

编辑 正如@huyz所指出的,不需要类型断言,因为
istodoto
是一个类型保护,所以这就足够了:

if (!isToDoDto(req.body)) {
    throw new Error("invalid request");
}

this.toDoService.addToDo(req.body);

下面是另一种强制类型转换的方法,即使在TS编译器通常抱怨的不兼容类型和接口之间:

export function forceCast<T>(input: any): T {

  // ... do runtime checks here

  // @ts-ignore <-- forces TS compiler to compile this as-is
  return input;
}
导出函数forceCast(输入:任意):T{
//…在这里进行运行时检查

//@ts ignore如果它对任何人都有帮助,我遇到了一个问题,我想将一个对象作为另一个具有类似接口的类型来处理。我尝试了以下操作:

没有通过脱毛

const x=新对象(a为b);
林特抱怨
a
缺少
b
上存在的属性。换句话说,
a
b
的一些属性和方法,但不是全部。为了解决这个问题,我遵循了VS code的建议:

通过了脱毛和测试

const x=新对象(a和b一样未知);

请注意,如果您的代码试图调用类型
b
上存在的属性之一,而该属性未在类型
a
上实现,则您应该意识到运行时错误。

请定义“它不工作”.准确地说。有错误吗?哪一个错误?在编译时?在运行时?会发生什么?在运行时,代码会正常执行,无论我传递什么对象。不清楚你在问什么。我的问题是如何将传入对象强制转换为类型化对象。如果强制转换不可能,请在运行时抛出异常,如Java、C#…这能回答吗你的问题?我不认为你需要强制转换
const toDo=req.body作为Itodoto;
,因为TS编译器知道它在这一点上是一个
Itodoto
,对于一般寻找类型断言的人,不要使用。这是不推荐的。使用
作为
“javascript中没有强制转换,所以你不能抛出if”铸造失败”我认为,更重要的是,TypeScript中的接口是不可操作的;事实上,它们是100%的。它们使得在概念上维护结构变得更容易,但对传输的代码没有实际的影响——在我看来,这是非常令人困惑的/反模式的,正如OP的问题所证明的。没有理由不匹配接口的东西不能传输JavaScript中的行;这是一个有意识的(而且很糟糕,依我看)TypeScript选择。@ruffin接口不是语法糖,但他们确实有意识地选择只在运行时使用。我认为这是一个很好的选择,这样在运行时就不会有性能损失。?TypeScript中接口的类型安全性不会扩展到传输的代码,甚至在运行前类型安全性也严重不足imited——正如我们在OP的问题中看到的,根本没有类型安全性。TS可以说,“嘿,等等,你的
any
还不能保证是
IToDoDto
”,但TS选择了不这样做。如果编译器只捕获一些类型冲突,而在传输的代码中没有(你是对的;我应该在原始版本中更清楚这一点),接口很不幸,[主要是?]sugar。我很高兴找到了这个答案,但请注意,如果您通过网络或其他应用程序发送“x”,可能会泄露个人信息(例如,如果“a”是用户),因为“x”仍然具有“a”的所有属性,它们对于typescript不可用。@ZoltánMatók这一点很好。另外,关于通过网络发送序列化对象,Java风格的getter和setter可以通过JavaScript
get
set
方法实现。
if (!isToDoDto(req.body)) {
    throw new Error("invalid request");
}

this.toDoService.addToDo(req.body);
export function forceCast<T>(input: any): T {

  // ... do runtime checks here

  // @ts-ignore <-- forces TS compiler to compile this as-is
  return input;
}
import { forceCast } from './forceCast';

const randomObject: any = {};
const typedObject = forceCast<IToDoDto>(randomObject);