In Vim9 script the type of the arguments is checked.  That helps you
writing correct functions, and once written it is easier to read back.
It does require a bit of extra text.
Here is an exmple that will help you:
	vim9script
	# Create a channel log so we can see what happens.
	ch_logfile('logfile', 'w')
	var shell_job: job
	# Function handling a line of text that has been typed.
	def TextEntered(text: string)
	  # Send the text to a shell with Enter appended.
	  ch_sendraw(shell_job, text .. "\n")
	enddef
	# Function handling output from the shell: Add it above the prompt.
	def GotOutput(channel: channel, msg: string)
	  append(line("$") - 1, "- " .. msg)
	enddef
	# Function handling the shell exits: close the window.
	def JobExit(job: job, status: number)
	  quit!
	enddef
	# Start a shell in the background.
	shell_job = job_start(["/bin/sh"], {
				 out_cb: GotOutput,
				 err_cb: GotOutput,
				 exit_cb: JobExit,
				 })
	new
	set buftype=prompt
	var buf = bufnr('')
	prompt_setcallback(buf, TextEntered)
	prompt_setprompt(buf, "shell command: ")
	# start accepting shell commands
	startinsert
-- 
hundred-and-one symptoms of being an internet addict:
115. You are late picking up your kid from school and try to explain
     to the teacher you were stuck in Web traffic.
 /// Bram Moolenaar -- Br...@Moolenaar.net -- 
http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- 
http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- 
http://ICCF-Holland.org    ///