在TypeScript

时间:2017-05-10 13:54:26

标签: object typescript interface casting

我试图在我的代码中使用快速(使用正文解析器中间件)的请求体转换到接口,但它无法正常工作。可以这样做吗?

这是我的界面:

export interface IToDoDto {
  description: string;
  status: boolean;
};

这是我试图进行演员表的代码:

@Post()
addToDo(@Response() res, @Request() req) {
  const toDo: IToDoDto = <IToDoDto> req.body;
  this.toDoService.addToDo(toDo);
  return res.status(HttpStatus.CREATED).end();
}

最后,调用的服务方法是:

public addToDo(toDo: IToDoDto): void {
  toDo.id = this.idCounter;
  this.todos.push(toDo);
  this.idCounter++;
}

我可以传递任何参数,这样可以正常工作。我已经读过在TypeScript中不存在转换但是类型断言,所以它只会告诉编译器一个对象的类型是x,所以......我错了吗?这样做的方法是什么?感谢。

3 个答案:

答案 0 :(得分:54)

javascript中没有强制转换,因此如果“强制转换失败”,则无法抛出 打字稿supports casting但这只是编译时间,你可以这样做:

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

您可以在运行时检查该值是否有效以及是否抛出错误,即:

function isToDoDto(obj: any): obj is IToDoDto {
    return typeof obj.description === "string" && typeof obj.status === "boolean";
}

@Post()
addToDo(@Response() res, @Request() req) {
    if (!isToDoDto(req.body)) {
        throw new Error("invalid request");
    }

    const toDo = req.body as IToDoDto;
    this.toDoService.addToDo(toDo);
    return res.status(HttpStatus.CREATED).end();
}

修改

正如@huyz指出的那样,不需要类型断言,因为isToDoDto是一个类型保护,所以这应该足够了:

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

this.toDoService.addToDo(req.body);

答案 1 :(得分:4)

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

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

请注意,为了减少复杂性,我在铸造前省略了您应该进行运行时检查的部分。我在项目中所做的工作是将我所有的.d.ts接口文件编译为JSON模式,并使用ajv在运行时进行验证。

答案 2 :(得分:0)

如果它可以帮助任何人,那么我有一个问题,我想将一个对象视为具有相似接口的另一种类型。我尝试了以下操作:

没有通过棉绒

const x = new Obj(a as b);

短毛绒抱怨a缺少b上存在的属性。换句话说,a具有b的某些属性和方法,但不是全部。要解决此问题,我遵循了VS Code的建议:

通过了棉签和测试

const x = new Obj(a as unknown as b);

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