diff --git a/src/components/Message.svelte b/src/components/Message.svelte
index edb5d63c99e6bad5b6aaa36a46290f278e4c132e..6f82a7cee200ae2f643340999c000fd61523b62b 100644
--- a/src/components/Message.svelte
+++ b/src/components/Message.svelte
@@ -1,7 +1,8 @@
-<script>
+<script lang="ts">
 	import { scale } from "svelte/transition";
-	import { removeMessage } from "$lib/messages";
-	export let message;
+	import { removeMessage } from "$lib/messages.js";
+	import type { Message } from "$lib/messages.js";
+	export let message: Message;
 </script>
 
 <style>
diff --git a/src/components/MessageComponent.svelte b/src/components/MessageComponent.svelte
index 20351c0718d7ef6436d4c11eeb5595dd2213f5e0..d8c88c4fb3b379c9ce22c8c125828c4c277e4c29 100644
--- a/src/components/MessageComponent.svelte
+++ b/src/components/MessageComponent.svelte
@@ -1,8 +1,6 @@
 <script>
 	import { messageStore } from "$lib/messages";
 	import Message from "./Message.svelte";
-	let messages;
-	messageStore.subscribe(val=>messages=val);
 </script>
 
 <style>
@@ -16,7 +14,7 @@
 </style>
 
 <div class="messages">
-	{#each messages as message (message.id)}
+	{#each $messageStore as message (message.id)}
 		<Message {message} />
 	{/each}
 </div>
diff --git a/src/lib/customcodes.js b/src/lib/customcodes.ts
similarity index 100%
rename from src/lib/customcodes.js
rename to src/lib/customcodes.ts
diff --git a/src/lib/flags.js b/src/lib/flags.ts
similarity index 100%
rename from src/lib/flags.js
rename to src/lib/flags.ts
diff --git a/src/lib/inputhandler.js b/src/lib/inputhandler.ts
similarity index 67%
rename from src/lib/inputhandler.js
rename to src/lib/inputhandler.ts
index 2795a164dc947a41dc241e41f303d3a0c5fc6271..187c013f576add62ffaa2d0c92efc7f93270046a 100644
--- a/src/lib/inputhandler.js
+++ b/src/lib/inputhandler.ts
@@ -1,11 +1,13 @@
 import { browser } from "$app/environment";
 
-const functions = new Map();
+type InputHandler = (input: string) => any;
 
-export function addInputHandler(handler, splitOnNewline = true) {
+const functions: Map<InputHandler, {keydown: (e: KeyboardEvent)=>void, paste: (e: ClipboardEvent)=>void}> = new Map();
+
+export function addInputHandler(handler: InputHandler, splitOnNewline: boolean = true): ()=>void {
 	if(!browser) return;
 	let input = "";
-	const keydown = (e) => {
+	const keydown = (e: KeyboardEvent) => {
 		if(e.key === "Enter"){
 			handler(input);
 			input = "";
@@ -19,7 +21,7 @@ export function addInputHandler(handler, splitOnNewline = true) {
 			input += e.key;
 		}
 	};
-	const paste = (e) => {
+	const paste = (e: ClipboardEvent) => {
 		const text = e.clipboardData.getData("text");
 		const lines = splitOnNewline ? text.split("\n") : [text];
 		for(const line of lines)
@@ -29,9 +31,10 @@ export function addInputHandler(handler, splitOnNewline = true) {
 	window.addEventListener("keydown", keydown);
 	window.addEventListener("paste", paste);
 	functions.set(handler, {keydown, paste});
+	return () => removeInputHandler(handler);
 }
 
-export function removeInputHandler(handler) {
+export function removeInputHandler(handler: InputHandler) {
 	if(!browser) return;
 	const funcs = functions.get(handler);
 	if(funcs) {
diff --git a/src/lib/messages.js b/src/lib/messages.js
deleted file mode 100644
index 14f85c831c62c78359d73f46c085c6884dc21a95..0000000000000000000000000000000000000000
--- a/src/lib/messages.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { writable } from "svelte/store";
-import { browser } from "$app/environment";
-
-let currMsgId;
-let messages;
-function loadMessageStore(){
-	if(browser){
-		const data = localStorage.getItem("messages") || "[]";
-		messages = JSON.parse(data);
-		currMsgId = messages.map(msg=>msg.id).reduce((max, id)=>Math.max(max, id), 0);
-		const store = new writable(messages);
-		store.subscribe(msgs=>{
-			messages = msgs;
-			localStorage.setItem("messages", JSON.stringify(msgs));
-		});
-		return store;
-	}
-	return new writable([]);
-}
-export const messageStore = loadMessageStore();
-export function addMessage(type, message){
-	if(browser) messageStore.update(messages => [...messages, {type, message, id: ++currMsgId}]);
-}
-export function removeMessage(message){
-	if(browser) messageStore.update(messages => messages.filter(m => m.id !== message.id));
-}
-export function getCurrentMessages(){
-	return messages;
-}
-
-export const MessageType = {
-	INFO: "info",
-	WARN: "warning",
-	WARNING: "warning",
-	ERROR: "error",
-	SUCCESS: "success",
-	DEFAULT: "default"
-};
diff --git a/src/lib/messages.ts b/src/lib/messages.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1e8b9e1765d206af8816e39eba90c94048291379
--- /dev/null
+++ b/src/lib/messages.ts
@@ -0,0 +1,50 @@
+import { writable, type Writable } from "svelte/store";
+import { browser } from "$app/environment";
+
+type MessageType = "info" | "warning" | "error" | "success" | "default";
+export type Message = {
+	type: MessageType,
+	message: string,
+	id: number,
+	duration?: number
+};
+
+let currMsgId: number;
+let messages: Message[];
+function loadMessageStore(): Writable<Message[]>{
+	if(browser){
+		const data = localStorage.getItem("messages") || "[]";
+		messages = JSON.parse(data);
+		currMsgId = messages.map(msg=>msg.id).reduce((max, id)=>Math.max(max, id), 0);
+		const store = writable(messages);
+		store.subscribe(msgs=>{
+			messages = msgs;
+			localStorage.setItem("messages", JSON.stringify(msgs));
+		});
+		return store;
+	}
+	return writable([]);
+}
+export const messageStore = loadMessageStore();
+export function addMessage(type: MessageType, message: string, duration?: number){
+	if(browser){
+		const msg = {type, message, id: ++currMsgId, duration};
+		messageStore.update(messages => [...messages, msg]);
+		return msg;
+	}
+}
+export function removeMessage(message: Message){
+	if(browser) messageStore.update(messages => messages.filter(m => m.id !== message.id));
+}
+export function getCurrentMessages(){
+	return messages;
+}
+
+export const MessageType = {
+	INFO: "info" as MessageType,
+	WARN: "warning" as MessageType,
+	WARNING: "warning" as MessageType,
+	ERROR: "error" as MessageType,
+	SUCCESS: "success" as MessageType,
+	DEFAULT: "default" as MessageType
+};
diff --git a/src/lib/server/authentication.js b/src/lib/server/authentication.ts
similarity index 50%
rename from src/lib/server/authentication.js
rename to src/lib/server/authentication.ts
index 79b3ecbee659f30b0495930e397e464eb1c480ab..85f01c1f67f5bc40b42ca88479cbd8d5faf77122 100644
--- a/src/lib/server/authentication.js
+++ b/src/lib/server/authentication.ts
@@ -1,31 +1,31 @@
 import { nanoid } from "nanoid";
 
-const sessions = new Map();
+const sessions: Map<string, string> = new Map();
 
-function generate() {
-	let token;
+function generate(): string {
+	let token: string;
 	do {
 		token = nanoid(32);
 	} while (sessions.has(token));
 	return token;
 }
 
-function getTokenForCard(card) {
+function getTokenForCard(card: string): string|undefined {
 	for (const [token, c] of sessions) {
 		if (c === card) return token;
 	}
 }
 
-export function generateSessionToken(card) {
+export function generateSessionToken(card: string): string {
 	const token = getTokenForCard(card) ?? generate();
 	sessions.set(token, card);
 	return token;
 }
 
-export function getCardFromSessionToken(sessionToken) {
+export function getCardFromSessionToken(sessionToken: string): string {
 	return sessions.get(sessionToken);
 }
 
-export function invalidateSessionToken(sessionToken) {
+export function invalidateSessionToken(sessionToken: string) {
 	sessions.delete(sessionToken);
 }
diff --git a/src/lib/server/database.js b/src/lib/server/database.ts
similarity index 91%
rename from src/lib/server/database.js
rename to src/lib/server/database.ts
index 0c13304bcb0f61857b6efb6d26b5fd4ecc9a9da4..8b1ec5386918a7f86d194a222de3e4bc1a2388ef 100644
--- a/src/lib/server/database.js
+++ b/src/lib/server/database.ts
@@ -1,4 +1,4 @@
-import prisma from "@prisma/client";
+import prisma, { PrismaClient } from "@prisma/client";
 import { Codes } from "$lib/customcodes";
 import { building } from "$app/environment";
 
@@ -11,7 +11,7 @@ function getDatabase(){
 	return db;
 }
 
-async function initDatabase(db){
+async function initDatabase(db: PrismaClient){
 	// While building the database is not needed and probably not even available
 	if(building) return;
 	
diff --git a/src/routes/admin/api/articles.js b/src/routes/admin/api/articles.ts
similarity index 65%
rename from src/routes/admin/api/articles.js
rename to src/routes/admin/api/articles.ts
index 10b35fbe0bb9236e2247013fcfd4556592792eb7..a18d6b566bbd17daee61ce65dc8fff7367903ac4 100644
--- a/src/routes/admin/api/articles.js
+++ b/src/routes/admin/api/articles.ts
@@ -1,11 +1,11 @@
 import { db } from "$lib/server/database";
 
-export function getPriceModifier(userBalance, noPremium=false){
+export function getPriceModifier(userBalance: number, noPremium: boolean = false){
 	if(noPremium===true) return ()=>0;
 	if (userBalance < 0) {
 		const debt = -userBalance;
 		const premium = 200 / (1 + Math.pow(Math.E, ((-debt + 2900) / 1000)));
-		return originalPrice=>{
+		return (originalPrice: number)=>{
 			if(originalPrice < 0) {
 				// just in case that some article should have a negative price (e.g. for refunds)
 				return 0;
@@ -18,7 +18,7 @@ export function getPriceModifier(userBalance, noPremium=false){
 			}
 		};
 	}else{
-		return originalPrice=>{
+		return (originalPrice: number)=>{
 			if (userBalance < originalPrice) {
 				// 10%, aber maximal 0,10€ Aufschlag
 				return Math.min(10, Math.ceil(0.1 * originalPrice));
@@ -29,7 +29,7 @@ export function getPriceModifier(userBalance, noPremium=false){
 	}
 }
 
-export function restockArticle(code, amount, cost){
+export function restockArticle(code: string, amount: number, cost: number){
 	return db.item.update({
 		where: {code},
 		data: {
@@ -43,27 +43,27 @@ export function restockArticle(code, amount, cost){
 	});
 }
 
-export async function restockArticles(restocks){
+export async function restockArticles(restocks: {code: string, amount: number, cost: number}[]){
 	return db.$transaction(restocks.map(({code, amount, cost})=>restockArticle(code, amount, cost)));
 }
 
-export async function createArticle(code, name, price, categoryId, image, available=true, show=true){
+export async function createArticle(code: string, name: string, price: number, categoryId: number, image: string, available=true, show=true){
 	return db.item.create({data: {code, name, price, categoryId, image, available, show}});
 }
 
-export async function updateArticle(code, name, price, categoryId, image, available, show){
+export async function updateArticle(code: string, name: string, price: number, categoryId: number, image: string, available: boolean, show: boolean){
 	return db.item.update({where: {code}, data: {name, price, categoryId, image, available, show}});
 }
 
-export async function createCategory(name, position){
+export async function createCategory(name: string, position: number){
 	return db.itemCategory.create({data: {name, position}});
 }
 
-export async function updateCategory(id, name, position){
+export async function updateCategory(id: number, name: string, position: number){
 	return db.itemCategory.update({where: {id}, data: {name, position}});
 }
 
-export async function deleteCategory(id){
+export async function deleteCategory(id: number){
 	return db.itemCategory.delete({where: {id}});
 }
 
diff --git a/src/routes/admin/api/notificationChannels.js b/src/routes/admin/api/notificationChannels.ts
similarity index 100%
rename from src/routes/admin/api/notificationChannels.js
rename to src/routes/admin/api/notificationChannels.ts
diff --git a/src/routes/admin/api/transactions.js b/src/routes/admin/api/transactions.ts
similarity index 100%
rename from src/routes/admin/api/transactions.js
rename to src/routes/admin/api/transactions.ts
diff --git a/src/routes/admin/api/users.js b/src/routes/admin/api/users.ts
similarity index 100%
rename from src/routes/admin/api/users.js
rename to src/routes/admin/api/users.ts
diff --git a/src/routes/api/transactions.ts b/src/routes/api/transactions.ts
index 3e62f3116bdce33fc07c45e5efd2f96454c1851c..12f769f8ef48fc8b72b02c4934d1f1cd6ac902b9 100644
--- a/src/routes/api/transactions.ts
+++ b/src/routes/api/transactions.ts
@@ -154,7 +154,42 @@ export async function fetchTransactions(userId: number, balanceAfterwards: numbe
 	/*
 	[limit]+1 items are fetched because then we can check if there are more items to fetch.
 	*/
-	const moneyTransactions = (await getMoneyTransactions(userId, before.moneyTransactions, limit+1)).map(transaction => ({
+	type MoneyTransaction = {
+		type: "transaction",
+		name: "Aufladen" | "Auszahlung",
+		difference: number,
+		createdAt: Date,
+		verified: boolean,
+		id: number,
+		balance?: number
+	};
+	type ItemTransaction = {
+		type: "item",
+		name: string,
+		difference: number,
+		premium: number,
+		createdAt: Date,
+		image: string,
+		id: number,
+		balance?: number
+	};
+	type MoneyTransfer = {
+		type: "transfer",
+		name: string,
+		difference: number,
+		createdAt: Date,
+		id: number,
+		balance?: number
+	};
+	type VoucherUse = {
+		type: "voucher",
+		name: string,
+		difference: number,
+		createdAt: Date,
+		id: number,
+		balance?: number
+	};
+	const moneyTransactions: MoneyTransaction[] = (await getMoneyTransactions(userId, before.moneyTransactions, limit+1)).map(transaction => ({
 		type: "transaction",
 		name: transaction.amount > 0 ? "Aufladen" : "Auszahlung",
 		difference: transaction.amount,
@@ -162,7 +197,7 @@ export async function fetchTransactions(userId: number, balanceAfterwards: numbe
 		verified: !!transaction.verifiedById,
 		id: transaction.id
 	}));
-	const itemTransactions = (await getItemTransactions(userId, before.itemTransactions, limit+1)).map(transaction => ({
+	const itemTransactions: ItemTransaction[] = (await getItemTransactions(userId, before.itemTransactions, limit+1)).map(transaction => ({
 		type: "item",
 		name: transaction.item.name,
 		difference: -(transaction.price + transaction.premium),
@@ -171,14 +206,14 @@ export async function fetchTransactions(userId: number, balanceAfterwards: numbe
 		image: transaction.item.image,
 		id: transaction.id
 	}));
-	const moneyTransfers = (await getMoneyTransfers(userId, before.moneyTransactions, limit+1)).map(transfer => ({
+	const moneyTransfers: MoneyTransfer[] = (await getMoneyTransfers(userId, before.moneyTransactions, limit+1)).map(transfer => ({
 		type: "transfer",
 		name: transfer.fromId === userId ? `Gesendet an ${transfer.to.name}` : `Empfangen von ${transfer.from.name}`,
 		difference: transfer.fromId === userId ? -transfer.amount : transfer.amount,
 		createdAt: transfer.createdAt,
 		id: transfer.id
 	}));
-	const voucherUses = (await getUsedVouchers(userId, before.voucherUses, limit+1)).map(voucher => ({
+	const voucherUses: VoucherUse[] = (await getUsedVouchers(userId, before.voucherUses, limit+1)).map(voucher => ({
 		type: "voucher",
 		name: `Gutschein ${voucher.code} eingelöst`,
 		difference: voucher.amount,
@@ -186,7 +221,7 @@ export async function fetchTransactions(userId: number, balanceAfterwards: numbe
 		id: voucher.id
 	}));
 	let transactions = [...moneyTransactions, ...itemTransactions, ...moneyTransfers, ...voucherUses]
-			.sort((a, b) => b.createdAt - a.createdAt);
+			.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
 	const hasMore = transactions.length > limit;
 	if(transactions.length > limit) transactions = transactions.filter((_,i)=>i<limit);
 	if (transactions.length > 0) {