Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check for the property type of an `unknown` value?

Tags:

typescript

I have the following function, which could receive an unknown value:

function formatReason(detail: unknown): string {
    if (detail
        && detail instanceof Object
        && detail.constructor.name === 'Object'
        && detail.hasOwnProperty('description')
        && typeof detail['description'] === 'number'
    ) {
        const output = detail['description'];
        return output;
    }

    return '';
}

The detail parameter could be any value. If it's an object with a description property of type string, the function should return that property value, otherwise empty string.

First, do you recommend using any or unknown for the detail parameter?

Second, no matter what I do, the type for output ends up to be any. How can I make sure it is string?

like image 225
Behrooz Avatar asked Aug 01 '18 01:08

Behrooz


People also ask

What is the type of unknown type?

New unknown top typeunknown is the type-safe counterpart of any . Anything is assignable to unknown , but unknown isn't assignable to anything but itself and any without a type assertion or a control flow based narrowing.

How do you access unknown objects in TypeScript?

Use a user-defined type guard to check if a value with unknown type contains a property in TypeScript. The user-defined type guard consists of a function that checks if the specific property is contained in the object and returns a predicate. Copied!

How do I know if a class has properties Typecript?

To check if a property exists in an object in TypeScript: Mark the specific property as optional in the object's type. Use a type guard to check if the property exists in the object. If accessing the property in the object does not return a value of undefined , it exists in the object.

When should you use the unknown keyword?

unknown and any are 2 special types that can hold any value. unknown is recommended over any because it provides safer typing — you have to use type assertion or narrow to a specific type if you want to perform operations on unknown .

How do I fix the error object is of type unknown?

The "Object is of type unknown" error occurs when we try to access a property on a value that has a type of unknown. To solve the error, use a type guard to narrow down the type of the object before accessing a property, e.g. if (err instanceof Error) {}.

How to check if a value contains a property in typescript?

Use a user-defined type guard to check if a value with unknown type contains a property in TypeScript. The user-defined type guard consists of a function that checks if the specific property is contained in the object and returns a predicate. We used a user-defined type guard to check if an object contains the name and age properties.

How to use unknown type variable in typescript?

With the unknown type, we have to first check the type that's currently stored in the variable before we get TypeScript support. The type is used when there's no way to know what the value stores in advance, so you can only access properties and methods on it by using type guards.

How do I find out if a property has been booked?

You can use the conventional way, by asking your bankers to check it. Just forward the property details, and they will call up their panel bank valuer and get a verbal indication. However, some bankers might be reluctant to check if you haven’t booked a property as they want a genuine client.


2 Answers

Edit: got corrected by Neon. The typeguard was not sufficient enough. I updated the example to explicitly assert an unknown value instead of an implicit any.


I'd recommend using unknown as it is the type-safe variant of any, that being said you probably want to use a type guard to assert the unknown value. This has the effect that the description property you're looking for is actually being asserted as a string and not as an any.

The typeguard (see the playground to see what IDescription is):

public hasDescription(obj: unknown): obj is IDescription {     return (obj as IDescription).description !== undefined         && typeof (obj as IDescription).description === "string"; } 

Using it in the codebase will result in an if-statement with some benefits.

if (this.hasDescription(detail)) {     // In this if-block the TypeScript compiler actually resolved the unknown type to the type described in the guard.     console.log(detail.description); } 

Here's a playground for you to see how that works (note how only 123 is being outputted to the console).


An example implementation for your specific problem:

function formatReason(detail: unknown): string {     if (this.hasDescription(detail) {         return detail.description;     }      return ''; }  
like image 152
Alex Avatar answered Sep 23 '22 22:09

Alex


There isn't a great way to write this code until this suggestion is implemented. In the meantime, it's up to you whether you prefer any or unknown (with some casts if you are using noImplicitAny, as I'd generally recommend). I wouldn't worry about the type of the output local variable because you've declared the return type of the function as string anyway.

like image 29
Matt McCutchen Avatar answered Sep 24 '22 22:09

Matt McCutchen