7

Is there a way how you can get immutability in typescript of function parameters? (the same from java with final)

Example:

function add(a: number, b: number): number {
    a = 5; // possible
    return a + b;
}

And what I am searching for, example:

function add(a: ???, b: ???): number {
    a = 5; // not possible because it would be immutable
    return a + b;
}

I am searching this because of clearity if a function can modify my parameters.

3
  • 1
    This is not a language feature. You can use a linter to handle this. ESLint rule, TSLint rule Commented Sep 8, 2020 at 12:11
  • 1
    Note that TSLint is deprecated. Commented Sep 8, 2020 at 12:23
  • 1
    Thank you its exactly what I was searching. Commented Sep 8, 2020 at 13:29

3 Answers 3

4

If you're looking for immutability to prevent your function from causing side effects, you can use the Readonly<T> type.

interface Person {
    name: string,
    age: number,
}

function add_age(person: Readonly<Person>) {
    person.age += 5; // not possible because it is immutable
}

add_age({ name: "Bob", age: 37 });
Sign up to request clarification or add additional context in comments.

2 Comments

Readonly only wraps fields of target type and does not prevent a = 5;. online compiler
@user7860670 indeed, but we don't care about reassigning a, since that'd be limited to the scope of our function. What we care about is modifying a parameter object in place and have side effects. Tho it's true that it's not what OP asked for.
3

It's a little hacky but you can enforce it like this

function add(...params: readonly [a: number, b: number]): number {
  const [a, b] = params;
  a = 5;
//^^^^^
//Cannot assign to 'a' because it is a constant.

  return a + b;
}

a and b are now constants and therefore immutable.

Note however that although params is readonly that only prevents you from doing things like pushing or splicing the tuple array. It won't prevent you from reassigning the array altogether

3 Comments

That's interesting, but I fail to see how it addresses the question because it can only be enforced via discipline and code review which could just as well enforce not reassigning parameters in the first place. It also clutters the code and makes it harder to understand the function's interface from the caller's perspective.
I don't disagree that it makes things harder to read and that it doesn't fix the problem that params could be reassigned. But a and b are constants and therefore immutable at the JavaScript level. Trying to reassign either a or b will result in a runtime error - in addition to it being a TS type error.
That's a great point about runtime validation. However, it seems purely a code readability and bug prevention issue.
1

In addition to Aron's answer, you could also allow add to take 0..n arguments and make them readonly:

function add(...args: readonly number[]): number {
    args[0] = 123; // not allowed!

    return args.length === 0 ? 0 
        : args.length === 1 ? args[0] 
        : args.reduce((a, b) => a + b);
}

add() // 0
add(123) // 123
add(123, 456) // 579
add(123, 456, 789) // 1368

...again, it's hacky but it works.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.