diff --git a/frontend/src/api.ts b/frontend/src/api.ts
index d5965da6100864e0ef0960842eafa1cbb0e0c8e0..029722cdb187e99772eba76551ceb185fda09243 100644
--- a/frontend/src/api.ts
+++ b/frontend/src/api.ts
@@ -1,6 +1,7 @@
 import axios from 'axios'
+import {Credentials} from "@/store/modules/authentication";
 
-function addFieldsToUrl ({url, fields = []}) {
+function addFieldsToUrl ({url, fields = []}: {url: string, fields?: string[]}) {
   return fields.length > 0 ? url + '?fields=pk,' + fields : url
 }
 
@@ -22,27 +23,27 @@ let ax = axios.create({
   }
 }
 
-export async function registerTutor (credentials) {
+export async function registerTutor (credentials: Credentials) {
   return ax.post('/api/tutor/register/', credentials)
 }
 
-export async function fetchJWT (credentials) {
-  const token = (await ax.post('/api/get-token/', credentials)).data.token
+export async function fetchJWT (credentials: Credentials): Promise<string> {
+  const token: string = (await ax.post('/api/get-token/', credentials)).data.token
   ax.defaults.headers['Authorization'] = `JWT ${token}`
   return token
 }
 
-export async function refreshJWT (token) {
-  const newToken = (await ax.post('/api/refresh-token/', {token})).data.token
+export async function refreshJWT (token: string): Promise<string> {
+  const newToken: string = (await ax.post('/api/refresh-token/', {token})).data.token
   ax.defaults.headers['Authorization'] = `JWT ${newToken}`
   return newToken
 }
 
-export async function fetchJWTTimeDelta () {
+export async function fetchJWTTimeDelta (): Promise<number> {
   return (await ax.get('/api/jwt-time-delta/')).data.timeDelta
 }
 
-export async function fetchUserRole () {
+export async function fetchUserRole (): Promise<string> {
   return (await ax.get('/api/user-role/')).data.role
 }
 
@@ -54,11 +55,11 @@ export async function fetchStudentSubmissions () {
   return (await ax.get('/api/student-submissions/')).data
 }
 
-export async function fetchSubmissionFeedbackTests ({pk}) {
+export async function fetchSubmissionFeedbackTests ({pk}: {pk: string}) {
   return (await ax.get(`/api/submission/${pk}/`)).data
 }
 
-export async function fetchAllStudents (fields = []) {
+export async function fetchAllStudents (fields: string[] = []) {
   const url = addFieldsToUrl({
     url: '/api/student/',
     fields
@@ -66,7 +67,8 @@ export async function fetchAllStudents (fields = []) {
   return (await ax.get(url)).data
 }
 
-export async function fetchStudent ({pk, fields = []}) {
+export async function fetchStudent ({pk, fields = []}:
+                                      {pk: string, fields?: string[]}) {
   const url = addFieldsToUrl({
     url: `/api/student/${pk}/`,
     fields
@@ -74,7 +76,7 @@ export async function fetchStudent ({pk, fields = []}) {
   return (await ax.get(url)).data
 }
 
-export async function fetchAllTutors (fields = []) {
+export async function fetchAllTutors (fields: string[] = []) {
   const url = addFieldsToUrl({
     url: '/api/tutor/',
     fields
@@ -86,16 +88,16 @@ export async function fetchSubscriptions () {
   return (await ax.get('/api/subscription/')).data
 }
 
-export async function deactivateSubscription ({pk}) {
+export async function deactivateSubscription ({pk}: {pk: string}) {
   const url = `/api/subscription/${pk}/`
   return (await ax.delete(url)).data
 }
 
-export async function fetchSubscription (subscriptionPk) {
+export async function fetchSubscription (subscriptionPk: string) {
   return (await ax.get(`/api/subscription/${subscriptionPk}/`)).data
 }
 
-export async function fetchAllFeedback (fields = []) {
+export async function fetchAllFeedback (fields: string[] = []) {
   const url = addFieldsToUrl({
     url: '/api/feedback/',
     fields
@@ -108,7 +110,8 @@ export async function fetchFeedback ({ofSubmission}) {
   return (await ax.get(url)).data
 }
 
-export async function fetchExamType ({examPk, fields = []}) {
+export async function fetchExamType ({examPk, fields = []}:
+                                       {examPk: string, fields?: string[]}) {
   const url = addFieldsToUrl({
     url: `/api/examtype/${examPk !== undefined ? examPk + '/' : ''}`,
     fields})
@@ -189,7 +192,7 @@ export async function deactivateAllStudentAccess () {
   return ax.post('/api/student/deactivate/')
 }
 
-export async function changePassword (userPk, data) {
+export async function changePassword (userPk: string, data) {
   return ax.patch(`/api/user/${userPk}/change_password/`, data)
 }
 
@@ -197,7 +200,7 @@ export async function getOwnUser () {
   return (await ax.get('/api/user/me/')).data
 }
 
-export async function changeActiveForUser (userPk, active) {
+export async function changeActiveForUser (userPk: string, active: boolean) {
   return (await ax.patch(`/api/user/${userPk}/change_active/`, {'is_active': active})).data
 }
 
diff --git a/frontend/src/components/feedback_list/FeedbackSearchOptions.vue b/frontend/src/components/feedback_list/FeedbackSearchOptions.vue
index 03e7d84f650080e083e1c9bfd2a11dba814c10dc..c5ec661f53854323718c3f67843e79355b9c4756 100644
--- a/frontend/src/components/feedback_list/FeedbackSearchOptions.vue
+++ b/frontend/src/components/feedback_list/FeedbackSearchOptions.vue
@@ -88,32 +88,26 @@ export default {
       items: [
         {
           name: 'showFinal',
-          path: 'showFinal',
           mutation: feedbackSearchOptsMut.SET_SHOW_FINAL
         },
         {
           name: 'searchOtherUserComments',
-          path: 'searchOtherUserComments',
           mutation: feedbackSearchOptsMut.SET_SEARCH_OTHER_USER_COMMENTS
         },
         {
           name: 'caseSensitive',
-          path: 'caseSensitive',
           mutation: feedbackSearchOptsMut.SET_CASE_SENSITIVE
         },
         {
           name: 'useRegex',
-          path: 'useRegex',
           mutation: feedbackSearchOptsMut.SET_USE_REGEX
         },
         {
           name: 'filterByTutors',
-          path: 'filterByTutors',
           mutation: feedbackSearchOptsMut.SET_FILTER_BY_TUTORS
         },
         {
           name: 'filterByStage',
-          path: 'filterByStage',
           mutation: feedbackSearchOptsMut.SET_FILTER_BY_STAGE
         }
 
diff --git a/frontend/src/components/submission_notes/RouteChangeConfirmation.vue b/frontend/src/components/submission_notes/RouteChangeConfirmation.vue
index ce5a4b26ded02686037e41fa744996fae411e8a8..362980ee6d7a14ad660374a0f8f25a67d6424e48 100644
--- a/frontend/src/components/submission_notes/RouteChangeConfirmation.vue
+++ b/frontend/src/components/submission_notes/RouteChangeConfirmation.vue
@@ -41,10 +41,8 @@ export default {
   watch: {
     nextRoute (newVal, oldVal) {
       if (newVal !== oldVal && this.$store.getters['submissionNotes/workInProgress']) {
-        console.log('here')
         this.dialog = true
       } else {
-        console.log('there')
         this.nextRoute()
       }
     }
diff --git a/frontend/src/store/modules/authentication.ts b/frontend/src/store/modules/authentication.ts
index ce8bbb045e98a85a10ec70e979ce41f116b25b11..b0101d5d3dc8faa74228139919d5eca2250b955e 100644
--- a/frontend/src/store/modules/authentication.ts
+++ b/frontend/src/store/modules/authentication.ts
@@ -1,9 +1,28 @@
 import * as api from '@/api'
 import gradySays from '../grady_speak'
+import {ActionContext, Module} from "vuex";
 
-function initialState () {
+export interface Credentials {
+    username: string,
+    password: string
+}
+
+interface AuthState {
+    token: string,
+    lastTokenRefreshTry: number,
+    refreshingToken: boolean,
+    jwtTimeDelta: number,
+    message: string,
+    user: {
+        pk: string,
+        username: string,
+        role: string,
+        is_admin: boolean
+    }
+}
+function initialState (): AuthState {
   return {
-    token: sessionStorage.getItem('token'),
+    token: sessionStorage.getItem('token') || '',
     lastTokenRefreshTry: Date.now(),
     refreshingToken: false,
     jwtTimeDelta: 0,
@@ -12,7 +31,7 @@ function initialState () {
       pk: '',
       username: '',
       role: '',
-      is_admin: ''
+      is_admin: false
     }
   }
 }
@@ -27,53 +46,53 @@ export const authMut = Object.freeze({
   SET_REFRESHING_TOKEN: 'SET_REFRESHING_TOKEN'
 })
 
-const authentication = {
+const authentication: Module<AuthState, any> = {
   state: initialState(),
   getters: {
     gradySpeak: () => {
       return gradySays[Math.floor(Math.random() * gradySays.length)]
     },
-    isStudent: state => {
+    isStudent: (state: AuthState) => {
       return state.user.role === 'Student'
     },
-    isTutor: state => {
+    isTutor: (state: AuthState)=> {
       return state.user.role === 'Tutor'
     },
-    isReviewer: state => {
+    isReviewer: (state: AuthState)=> {
       return state.user.role === 'Reviewer'
     },
-    isTutorOrReviewer: (state, getters) => {
+    isTutorOrReviewer: (state: AuthState, getters) => {
       return getters.isTutor || getters.isReviewer
     },
-    isLoggedIn: state => !!state.token
+    isLoggedIn: (state: AuthState) => !!state.token
   },
   mutations: {
-    [authMut.SET_MESSAGE] (state, message) {
+    [authMut.SET_MESSAGE] (state: AuthState, message: string) {
       state.message = message
     },
-    [authMut.SET_JWT_TOKEN] (state, token) {
+    [authMut.SET_JWT_TOKEN] (state: AuthState, token: string) {
       sessionStorage.setItem('token', token)
       state.token = token
     },
-    [authMut.SET_JWT_TIME_DELTA] (state, timeDelta) {
+    [authMut.SET_JWT_TIME_DELTA] (state: AuthState, timeDelta: number) {
       state.jwtTimeDelta = timeDelta
     },
-    [authMut.SET_USER] (state, user) {
+    [authMut.SET_USER] (state: AuthState, user) {
       state.user = user
     },
-    [authMut.SET_REFRESHING_TOKEN] (state, refreshing) {
+    [authMut.SET_REFRESHING_TOKEN] (state: AuthState, refreshing: boolean) {
       state.refreshingToken = refreshing
     },
-    [authMut.SET_LAST_TOKEN_REFRESH_TRY] (state) {
+    [authMut.SET_LAST_TOKEN_REFRESH_TRY] (state: AuthState) {
       state.lastTokenRefreshTry = Date.now()
     },
-    [authMut.RESET_STATE] (state) {
+    [authMut.RESET_STATE] (state: AuthState) {
       sessionStorage.setItem('token', '')
       Object.assign(state, initialState())
     }
   },
   actions: {
-    async getJWT (context, credentials) {
+    async getJWT (context: ActionContext<AuthState, any>, credentials: Credentials) {
       try {
         const token = await api.fetchJWT(credentials)
         context.commit(authMut.SET_JWT_TOKEN, token)
diff --git a/frontend/src/util/helpers.ts b/frontend/src/util/helpers.ts
index a582d317c68566142c6babbd593476a511756321..73e8fc494ab7352061c72fd6e696831b58973e6e 100644
--- a/frontend/src/util/helpers.ts
+++ b/frontend/src/util/helpers.ts
@@ -1,11 +1,12 @@
+import vueInstance from '@/main.ts'
 
-export function nameSpacer (namespace) {
-  return function (commitType) {
+export function nameSpacer (namespace: string) {
+  return function (commitType: string) {
     return namespace + commitType
   }
 }
 
-export function getObjectValueByPath (obj, path) {
+export function getObjectValueByPath (obj: any, path: string): any {
   // credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621
   if (!path || path.constructor !== String) return
   path = path.replace(/\[(\w+)\]/g, '.$1') // convert indexes to properties
@@ -22,6 +23,11 @@ export function getObjectValueByPath (obj, path) {
   return obj
 }
 
+interface GetSetPair {
+    get: () => any,
+    set: (val: object) => void
+}
+
 /**
  * Use this method to generate a computed property accessing the store for a Vue instance.
  * The get method will return the value at this.$store.state.<path>.
@@ -31,17 +37,29 @@ export function getObjectValueByPath (obj, path) {
  * @param namespace to prepend the mutation type with
  * @returns {*}
  */
-export function createComputedGetterSetter ({path, mutation, namespace}) {
+export function createComputedGetterSetter (
+    {path, mutation, namespace}:
+        {path: string, mutation: string, namespace:string}): GetSetPair {
   return {
-    get () {
-      return getObjectValueByPath(this.$store.state, path)
+    get (): any {
+      return getObjectValueByPath(vueInstance.$store.state, path)
     },
-    set (val) {
-      this.$store.commit(`${namespace ? namespace + '/' : ''}${mutation}`, val)
+    set (val: object): void {
+      vueInstance.$store.commit(`${namespace ? namespace + '/' : ''}${mutation}`, val)
     }
   }
 }
 
+interface StateMapperItem {
+    name: string,
+    mutation: string,
+    path?: string
+}
+
+interface MappedState {
+    [key: string]: GetSetPair
+}
+
 /**
  * Returns an object of generated computed getter/setter pairs.
  * Can be used to quickly bind a stores state and corresponding setters to a vue component
@@ -49,12 +67,14 @@ export function createComputedGetterSetter ({path, mutation, namespace}) {
  * @param pathPrefix if set, all items path will be prepended by the path prefix
  * @param items array that contains objects {name, path, mutation}
  */
-export function mapStateToComputedGetterSetter ({namespace = '', pathPrefix = '', items = []}) {
-  return items.reduce((acc, curr) => {
+export function mapStateToComputedGetterSetter (
+    {namespace = '', pathPrefix = '', items = []}:
+        {namespace: string, pathPrefix: string, items: StateMapperItem[]}): MappedState {
+  return items.reduce((acc: MappedState, curr) => {
     // if no path is give, use name
     const itemPath = curr.path || curr.name
     const path = pathPrefix ? `${pathPrefix}.${itemPath}` : itemPath
-    acc[curr.name] = createComputedGetterSetter({...curr, path, namespace})
+    acc[curr.name] = createComputedGetterSetter({mutation: curr.mutation, path, namespace})
     return acc
   }, {})
 }
@@ -67,13 +87,13 @@ export function cartesian (a, b, ...c) {
 }
 
 // flatten an array
-export function flatten (list) {
+export function flatten (list: any[]): any[] {
   return list.reduce(
     (a, b) => a.concat(Array.isArray(b) ? flatten(b) : b), []
   )
 }
 
-export function objectifyArray (arr, key = 'pk') {
+export function objectifyArray<T> (arr: T[], key = 'pk'): {[key: string]: T} {
   return arr.reduce((acc, curr) => {
     acc[curr[key]] = curr
     return acc
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index c19146b1b3e969da65d682034ed2a4d7ab81487e..c800f3ea8e347d2dbec47be5b999bd78f2e119d3 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -2,7 +2,7 @@
   "compilerOptions": {
     "target": "esnext",
     "module": "esnext",
-    "strict": true,
+    "strict": false,
     "jsx": "preserve",
     "importHelpers": true,
     "moduleResolution": "node",
@@ -16,7 +16,7 @@
       ]
     },
     "lib": [
-      "es2015",
+      "es2017",
       "dom",
       "dom.iterable",
       "scripthost"
diff --git a/frontend/vue.config.js b/frontend/vue.config.js
index 29c09438239fdf4ccbc1d99b034bce7922b8792a..d321253997a1fc75cc8b2ed0b9aabd624ded3303 100644
--- a/frontend/vue.config.js
+++ b/frontend/vue.config.js
@@ -5,7 +5,8 @@ const projectRoot = path.resolve(__dirname)
 module.exports = {
   assetsDir: 'static',
   devServer: {
-    allowedHosts: ['localhost']
+    allowedHosts: ['localhost'],
+    host: 'localhost'
   },
   configureWebpack: {
     resolve: {