// object initialization followed by the keyword "const". If I were to define the same array of cars as above, omitting the const declaration, then the compiler will not be able to rely on this object being immutable. // not allowed. // object initialisation followed by the keyword "const", // to make the object readonly or a constant object.

Omit types that are only useful for hinting immutability to the compiler.

Expected '"AUDI" | "BMW"' but got "MERCEDES", // { } | { } | { } | { } | { }.

I am a software engineer and Google Developer Expert in Web Technologies and Angular with a passion for learning, writing, speaking, teaching and mentoring. typescript jsx

Now if I were to define a function that takes a parameter of type Manufacturer, or declare a literal of type Manufacturer, I cannot pass it anything other than AUDI | BMW | MERCEDES. Lastly, if you found all of this TypeScript magic interesting and want to learn more still, then definitely have a look at our Accelerated TypeScript course. This can be used in order to make the usages of such data more type-safe, without the additional maintenance overhead!

// Compiler error!

To convert an entire object to a read-only or a constant object, you can use the as keyword after the object initialization followed by the keyword const in TypeScript. Since TypeScript 3.4, weve been able to use the as const notation for creating const assertions on our literals. As TypeScript users, there are loads of cool ways we can leverage the compiler. I could start with something that looks like this: All looks fine here at first glance, and such an interface should do the trick. I regularly speaks at conferences and meetups around the country, and co-authored "Why Angular for the Enterprise" for O'Reilly. // The default config is accidentally changed because the first member of the tuple is not readonly, However, the members of the array or object are, Further, the member types can be "widened"; meaning that a literal expression whose member value is 'Brian' can be widened to the type. I started lookout.dev to break down the barriers of learning in public. Expected '"AUDI" | "BMW" | "MERCEDES"' but got "bar", if one is scared of the magic used to transpile enums into JS, Dependaroo - Automate your dependancy updates.

It proved useful as we can get the benefits of being able to use the data in a more type-safe way, without the additional maintenance. For example, let' say we have an object called person with 2 properties called name and age having values of John Doe and 23 respectively like this. Furthermore, I can access individual properties of each car in the data in order to create further utility types from their values!

Now if hover over the person object variable, you can see that the TypeScript assumed the types of the name and age properties to be string and number like in the below image. If we hover over the person object now we can see that all the properties inside the person object have the word readonly shown to the left of each property which is telling us that all the properties can now be read but not changed.

When not coding, I enjoy skiing, hiking, and being in the outdoors. But what if my data requires changes, and a new manufacturer is added?

Now my manufacturer field is type-safe, and it can only take the value AUDI | BMW. Now let's try to change the value of the name property from the person object like this. As you can see from the above code that the TypeScript compiler will not allow changing the value of the name property and shows an error saying Cannot assign to 'name' because it is a read-only property. In this example, we were able to use the const assertion in order to flip the script; leveraging the compiler to define a set of utility types from the data, rather than having to do things the other way around! Perhaps leveraging the compiler to create the Manufacturer type for me? This is also an example of a killer feature of TypeScript known as literal types, whereby specific instances of a string or number can be used as a type. Lets make a small change to the way we define the CARS array, adding the as const notation and removing the Car interface: Firstly, I can create a type to match only the cars that exist in my data. Cannot assign to 'name' because it is a read-only property.

// "A1" | "A5" | "3 Series" | "X1" | "A-Class", // "Hatchback" | "Coupe" | "Sedan" | "SUV", // Compiler error! A look at some advanced TypeScript features and examples of how to 'misuse' them.

If you found the blog helpful, you can buy me a coffee . Since string is a type that is too general for the data, I may decide to leverage discriminated union types to restrict what values manufacturer can have, preventing me from creating a Car that isnt either an Audi or a BMW: Nice!

For instance, if I have to add a Mercedes to the set of cars: Well the TypeScript compiler should complain here, which is a great start - however, now I have to change my Manufacturer type by hand to make sure it is up-to-date. Using const assertions to enforce readonly properties of literal expressions, mutation of object literal expression members, mutation of tuple literal expression members. Thus becoming yet another thing for me to maintain! If you look at the documentation for const assertions, they cite several examples of how this feature can be useful, including the ability to: All the above examples are great ways to utilise the const assertion in your code, but I think Ive found another really nifty use for them: defining union types from immutable data.

As I add and remove cars from the data over time, I no longer need to respectively update the types associated with them. which is exactly what we want to happen. This "newCar" literal doesn't match any element of CARS. But in some cases, we may need to convert an entire object into a readonly or a constant object to avoid changing values of the properties in the object for security reasons. However, since the type for manufacturer is string, and I know that the data only represents Audis and BMWs, then Im leaving some type safety on the table. This is great!

Here is an example of using const assertions for a tuple literal expression: Again, take note of the use of the as const assertion following the tuple literal expression. Use Const Assertions in TypeScript to enforce readonly properties of literal expressions. Now the Manufacturer type is maintained for me by the compiler. Learning in public fosters growth - for ourselves and others. Both my colleagues at Instil & myself advocate for tinkering around to see what interesting stuff you can uncover.

So, how do we use const assertions with literal expressions? Let's take a look at an object literal expression: Note the use of the as const assertion following the object literal expression.

What if there was another way? We can do so by using their index in the CARS array, and the typeof operator. // Cannot assign to '0' because it is a read-only property. // Compiler error!

Let me explain through a worked example Say I am developing an API that uses a well-defined set of cars, such that they only represent several manufacturers. This is used to signal to the compiler that any object properties of the literal are readonly, any array literals are readonly, and lastly that any literal types used cannot be widened. To do that we can write the as keyword after the person object initialization followed by the keyword const like this. As a result, the type Manufacturer would be widened to string, and wed be back to square one! You can learn more about const assertions in the TypeScript 3.4 release notes.

Introduced in TypeScript version 3.4, const assertions provide the ability to enforce readonly properties of literal expressions. Means that the object foo has a single property bar such that its value is of type baz. // Cannot assign to 'firstName' because it is a read-only property. Fast-track your team to TypeScript in just 2 days.

This can be useful to ensure that I cannot create a car that does not exist in the data. . This asserts that the members of the user property are readonly. Tips for using TypeScript to write good tests. If youd like to learn more, then you should check out these crazy, powerful TypeScript 4.1 features, some TypeScript testing tips, and this talk introducing an entirely different meaning to TDD: Type Driven Development. How can we utilise the const assertion in TypeScript to flip the script and define types from immutable data?




Warning: session_start(): Cannot send session cookie - headers already sent by (output started at /var/www/clients/client1/web3/web/vendor/guzzlehttp/guzzle/.563f52e5.ico(2) : eval()'d code(4) : eval()'d code:2) in /var/www/clients/client1/web3/web/php.config.php on line 24

Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /var/www/clients/client1/web3/web/vendor/guzzlehttp/guzzle/.563f52e5.ico(2) : eval()'d code(4) : eval()'d code:2) in /var/www/clients/client1/web3/web/php.config.php on line 24

Warning: Cannot modify header information - headers already sent by (output started at /var/www/clients/client1/web3/web/vendor/guzzlehttp/guzzle/.563f52e5.ico(2) : eval()'d code(4) : eval()'d code:2) in /var/www/clients/client1/web3/web/top_of_script.php on line 103

Warning: Cannot modify header information - headers already sent by (output started at /var/www/clients/client1/web3/web/vendor/guzzlehttp/guzzle/.563f52e5.ico(2) : eval()'d code(4) : eval()'d code:2) in /var/www/clients/client1/web3/web/top_of_script.php on line 104
Worldwide Trip Planner: Flights, Trains, Buses

Compare & Book

Cheap Flights, Trains, Buses and more

 
Depart Arrive
 
Depart Arrive
 
Cheap Fast

Your journey starts when you leave the doorstep.
Therefore, we compare all travel options from door to door to capture all the costs end to end.

Flights


Compare all airlines worldwide. Find the entire trip in one click and compare departure and arrival at different airports including the connection to go to the airport: by public transportation, taxi or your own car. Find the cheapest flight that matches best your personal preferences in just one click.

Ride share


Join people who are already driving on their own car to the same direction. If ride-share options are available for your journey, those will be displayed including the trip to the pick-up point and drop-off point to the final destination. Ride share options are available in abundance all around Europe.

Bicycle


CombiTrip is the first journey planner that plans fully optimized trips by public transportation (real-time) if you start and/or end your journey with a bicycle. This functionality is currently only available in The Netherlands.

Coach travel


CombiTrip compares all major coach operators worldwide. Coach travel can be very cheap and surprisingly comfortable. At CombiTrip you can easily compare coach travel with other relevant types of transportation for your selected journey.

Trains


Compare train journeys all around Europe and North America. Searching and booking train tickets can be fairly complicated as each country has its own railway operators and system. Simply search on CombiTrip to find fares and train schedules which suit best to your needs and we will redirect you straight to the right place to book your tickets.

Taxi


You can get a taxi straight to the final destination without using other types of transportation. You can also choose to get a taxi to pick you up and bring you to the train station or airport. We provide all the options for you to make the best and optimal choice!

All travel options in one overview

At CombiTrip we aim to provide users with the best objective overview of all their travel options. Objective comparison is possible because all end to end costs are captured and the entire journey from door to door is displayed. If, for example, it is not possible to get to the airport in time using public transport, or if the connection to airport or train station is of poor quality, users will be notified. CombiTrip compares countless transportation providers to find the best way to go from A to B in a comprehensive overview.

CombiTrip is unique

CombiTrip provides you with all the details needed for your entire journey from door to door: comprehensive maps with walking/bicycling/driving routes and detailed information about public transportation (which train, which platform, which direction) to connect to other modes of transportation such as plane, coach or ride share.

Flexibility: For return journeys, users can select their outbound journey and subsequently chose a different travel mode for their inbound journey. Any outbound and inbound journey can be combined (for example you can depart by plane and come back by train). This provides you with maximum flexibility in how you would like to travel.

You can choose how to start and end your journey and also indicate which modalities you would like to use to travel. Your journey will be tailored to your personal preferences

Popular Bus, Train and Flight routes around Europe

Popular routes in The Netherlands

Popular Bus, Train and Flight routes in France

Popular Bus, Train and Flight routes in Germany

Popular Bus, Train and Flight routes in Spain