TypeScript strict class / interface

I am using TypeScript version 2.3.4. I want to write a function that takes an object that must have the specified fields. But this object should not contain any other fields. How can I achieve this?

Now this only works if I define an inline object. But if I use another object with additional fields, this will allow the compiler. Which is completely wrong.

Example:

function foo(arg: { a: string }) { // there is tons of fields actually // ... } foo ({a: "qwerty"}); // No Error - ok foo ({a: "qwerty", b: 123}); // Error - ok let bar = { a: "qwerty", b: 123 }; foo (bar); // No Error - NOT OK !!! 

The same code can be called with interfaces, classes, type declarations - this is the same problem.

Now I need to extract the fields from the object manually to make sure that there are no additional fields. But I can not extend this solution to ~ 1000 functions (I really need it) throughout the code - this is too dirty. I am creating an API wrapper and I need to make sure that no additional or incorrect fields are added to the server.

+8
typescript
source share
4 answers

The function you request is called " exact types ".

This is considered, that is, not rejected and not accepted, and the discussion continues.

+2
source share

Necromancy.
It comes with typescript 2.4:

 type foo = { a:string; b:number; opt?:string; } function test(obj:foo) {} test({ a:"", b:123, e:"produceError"}); 

And to force the use of the object, if all parameters are optional:

 function test(obj:foo & object) {} 

And if you want to pass either a string or another type of object:

 function test(obj: string | foo & object) {} 
+2
source share

Here's how it works by design, and I'm not sure if you can do it. See the docs for more details .

What you also do wrong - you cannot be 100% sure that it is sent to the server. As long as the browser does not know anything about TS, some library can enter everything that it needs into any request, for example. by overwriting the XmlHttpRequest methods (this is, for example, no less than angular zone.js).

Another way to easily break your intentions is as simple as using <any> before any parameter passed.

TypeScript is designed to improve your development process, but I don't think it can be used for your needs. This is usually covered by writing proper tests.

+1
source share

There is a way, but you have to implement it yourself. It is called "User Defined Type Guard", and it looks like this:

 interface Test { prop: number; } function isTest(arg: any): arg is Test { return arg && arg.prop && typeof(arg.prop) == 'number'; } 
+1
source share

All Articles