How to access properties of Office.js objects that don’t exist in the Typescript definition file
When developing Office Add-ins and using Typescript, I’ve found the Office.js Typescript definition file available at DefinatelyTyped to only support a fraction of the objects and properties that are available within the Office.js library.
To give you an idea of what I mean, here is a list of properties that are available on the Office.context.mailbox.item object (according to the API documentation in the Outlook Dev Center)
And here are all the properties of that same object using the Typescript definition file:
I was left wondering where the rest of the properties were. They simply don’t exist in the Typescript definition file. So this leaves us in a bit of a bind, because we are using Typescript we can’t just reference a property that doesn’t exist in the Typescript definition file (even though we know the property will exist at run-time). The Typescript compiler will do it’s job well and throw up a compile time error that the property does not exist.
Without going to the effort of taking the Office.js Typescript definition file and extending it yourself to start filling it out you may want to consider the following work around.
We can declare an object in Typescript without a specific type by specifying it’s type as any. If we do this to an object within the Office.js library we can get an un-typed handle to the object. As the object in now un-typed, we can call any property of that object we like (whether it exists or not). Below is the code that will give us access to the subject of the email that is not available in the Typescript definition file.
If the property exists at runtime then great, if not then we will get a run-time error. It is definitely a step backwards and is why we use Typescript in the first place!
It would get a bit unwieldy if you used this technique throughout your code, and I’d like to think that as we get updated Office.js Typescript definition files that we can remove this type of code from our project and access the properties in a properly typed way. To isolate your use of this technique to a central location and facilitate removing the code later on, I’d suggest creating a class that takes in the object (e.g. Office.context.mailbox.item) then inside the class it gets the un-typed handle to the item and provides methods or properties that return the missing properties (with the bonus that the values returned can have a type associated with them). Below is an example of a class with static methods that provide typed access to missing properties on a mailbox item.
Hopefully the Office team will see the value in publishing current and complete Typescript definition files so we don’t have to write code like this in future.