There isn't a way to require that the caller literally writes as const as part of the parameter. You probably don't even really want that anyway; presumably you just want the function to require that arg be of a numeric literal type instead of the number type.
The first step toward achieving this is to give the compiler a hint that you want the type of arg to be inferred as a numeric literal if possible... this would be more like requesting a const assertion interpretation of the input instead of requiring it. There's no similar syntax like as const in the call signature side, (see microsoft/TypeScript#30680 for a relevant feature request), but there are other ways to get this behavior. You could make func() a generic function and have the type parameter T be constrained to number. A type constraint like T extends number is a hint that the compiler should try to infer a numeric literal for T instead of number. (See microsoft/TypeScript#10676 which implements and describes this behavior).
So let's try it:
function func<T extends number>(arg: T) { }
func(1 as const); // function func<1>(arg: 1): void
func(1); // no error, but function func<1>(arg: 1): void
Here the compiler infers that T is 1 (and not number) in both the func(1 as const) call, as well as the plain func(1) call. This is probably even better than spewing errors when you call func(1), right?
That's great, but it still doesn't prevent number from being passed, like this:
let someNumber: number = 1;
func(someNumber); // no error,
// function func<number>(arg: number): void
To truly prevent that, we need to get creative with our generic constraints, and employ conditional types:
type SomeNumericLiteral
= 1 | 2 | 3; // just a dummy numeric literal union to make the error nice
function func<T extends (number extends T ? SomeNumericLiteral : number)>(
arg: T) { }
What I've done there is to have the compiler look at arg and infer T. It then checks that it is assignable to number extends T ? SomeNumericLiteral : number. If T is inferred as a numeric literal, or really any type that isn't number or some supertype of it, then the conditional type collapses to number, and it behaves the same as before with just T extends number:
func(1 as const); // function func<1>(arg: 1): void
func(1); // function func<1>(arg: 1): void
On the other hand, if T is inferred as number or some supertype of it, then the conditional type collapses to SomeNumericLiteral, and T extends SomeNumericLiteral will fail the constraint, because number or some supertype does not extend SomeNumericLiteral by design:
let someNumber: number = 1;
func(someNumber); // error!
// ~~~~~~~~~~
// Argument of type 'number' is not assignable to parameter of type 'SomeNumericLiteral'.
Note that I defined SomeNumericLiteral as 1 | 2 | 3, but we just needed to use some type that number doesn't extend to make a compiler error happen; I chose 1 | 2 | 3 since hopefully that will make the error message nicer in cases people pay close attention to it. The usual go-to thing to write is never instead of SomeNumericLiteral, but that makes a weird message.
So there you go... now func() only accepts numeric literals and rejects number.
Playground link to code