So now after all these features where we work with the type stem cells so to say where we worked on
checking types costing two times let's come back to features that help us write flexible code.
Of course still relate the two types it is typescript after all but not so much focused on just the
types and how we can manage them.
And for that I want to start with index types a feature that allows us to create objects which are more
flexible regarding the properties they might hold.
Now what do you mean by that.
Let's say you're writing an application where you're validating some user input.
So you have multiple input fields and depending on what the user enters steer and which field it is
you might want to store and eventually show different error messages.
For example if it's an email field you want to check whether it is an email and if it is not you want
to add a proper error message to some error container.
So that's what I'll start with I will have my interface error or container here and that should be an
object hence I user interface here but it should be flexible regarding what it holds ultimately my goal
is that with that we can create objects where we have some error identifier which could be the idea
of the input field to which the error belongs.
For example email and then some error string not a valid email and then we have another property let's
say user name and then an error a string we might be storing for Dad input field if the input is incorrect
must start with a character something like that should be stored in that object.
The problem with that is I don't know in advance which exact property names that we'll have in here.
You could say well we'll have email and user name but for one I want this to be a flexible container.
I want to be able to use it on any form I have in my web page and I might have different forums with
different inputs with different identifiers.
So I don't want to restrict myself to just or email and user name errors.
And in addition even if we always had just email and user name inputs and we just want to store arrows
for those what do we do if just the email is invalid and not the user name then of course in his object
we could store now as a value for a user name.
But I'd like to just admit it.
So did we have an object which only holds properties for inputs where we have an error so that we can
always loop food as object with a for in loop to read all the errors we got for example and don't have
any properties in there which don't actually store an error.
So long story short I need an object where I'm pretty clear regarding the value type it should be a
string but where I don't know in advance how many properties I'll have and which name the properties
will have.
And for such a scenario we can use index types.
You define the index type by using square brackets here remember normally we would write a property
name here but now we use square brackets then any name of your choice for example a key or prop then
a colon.
And then the value type of the property and then an object you can't have strings numbers or as symbols
as a property.
You for example can't use boolean here.
That's not allowed but you can use string here with that and simply saying that whatever object I'm
constructing based on this error container interface later must have properties which are strings user
name for example would be a valid string even if I don't rapid in quotes.
Then we add a colon and then the value type which is string.
So with that I'm saying I don't know the exact property name.
I also don't know do property count.
I just know that every property which is added to does object which is based on error container must
have a property name which can be interpreted as a string and the value for that property also must
be a string.
That's what I'm saying here.
Now with that we also still can add predefined properties however only if they're of the same type as
this year.
So we could add an idea which is of type String and then any object we build that adheres to this interface
must have an I.D. property and can add as many other properties as it once.
But we can't set I.D. to a number here for example because we have an index type here.
So that is a restriction we have.
If we build such an object so now what's the consequence.
Now we can create an error bag for example which is of type error container which therefore is an object
and it would be valid like this because we don't have to add any properties that is all valid.
But of course we can now add some for example email not a valid email and this is OK it would not be
OK if I instead assigned a number here because we're saying every property needs a string value type
so we must use a string here.
If I use a number here that would work because that can be interpreted as a string as well so I can
also use a number as a key type here if I wanted to.
I'm pretty free regarding what I use here if it would change the prop type here to No.
Then you can do that and this would be OK but this wouldn't because email is not a number DESC can't
be converted to a number it can be treated as a string but not as a number.
So this is how you control which type of properties or which property names you allow.
And here I indeed want to allow a string property names so anything which can be converted to a string
is a valid property name.
And then the value has to be a string as well.
And as I said Of course now we can add multiple values here multiple properties I should say must start
with a capital character.
So this is now such a error back we could build with the help of our container which gives us this extra
flexibility that we don't need to know in advance which property names we want to use and how many properties
we need.