如何在带有打字稿的函数中包含输出参数



是否可以使用 TypeScript 在函数中包含输出参数?类似于 C# 中的Func1(string val1, int out k1, int out k2)

目前没有。

可以返回可以包含多个属性的对象。

return { k1: 5, k2: 99 };

你可以把它与解构结合起来,这样中间对象就变得不可见了......

function myFunction() {
    return { k1: 5, k2: 99 };
}
const { k1, k2 } = myFunction();
console.log(k1);
console.log(k2);

你也可以用元组实现相同的目标,但这是非常可读的。

这是另一种方式。定义一个回调函数,它将包含您的 out 参数:

function Func1(val1: string, out: (k1: number, k2: number) => void): void {
    out(1, 2);
}

如何使用它的示例:

function anotherFunction(): void {
    let k1: number;
    let k2: number;
    Func1("something", (v1, v2) => {
        k1 = v1;
        k2 = v2;
    });
    console.log(k1); // output: 1
    console.log(k2); // output: 2
}

我发现它对这样的东西最有用:

const keys: string[] = [];
const values: number[] = [];
function tryGet(key: string, out: (value: number) => void): void {
    const index = keys.indexOf(key);
    if (index >= 0) {
        out(values[index]);
    }
}
function test(): void {
    const key = "myValue";
    tryGet(key, (value) => {
        console.log(`Key '${key}' exist with value ${value}`);
    });
}

Typescript 使用"按值调用"传递所有参数。但是,如果参数是引用,则在大多数情况下,其行为类似于"按引用调用"。可以为基元类型编写包装类。下面是一些代码:

var func=function(param:Str){
    param.str="modified";
}
class Str{
    str:string="unmodified";
}
var test:Str=new Str();
alert(test.str); //alerts "unmodified"
func(test);
alert(test.str); //alerts "modified"

不过,您需要小心:

var func=function(param:Str){
    param=new Str("modified");
}
class Str{
    str:string;
    constructor(param:string){
        this.str=param;
    }
}
var test:Str=new Str("unmodified");
alert(test.str); //alerts "unmodified"
func(test);
alert(test.str); //alerts "unmodified"

函数参数"按值调用"传递。因此,在函数体中,您正在使用引用的副本。此引用指向与作为参数传递的引用相同的对象,因此您可以访问其成员并对其进行修改。但是,如果将新对象指定给引用,则所有进一步的更改都将应用于此新对象。因此,上面的代码打印两次未经修改。我认为 C# 也是这样工作的。

通常,您只需返回一个具有多个属性的对象,其中一个属性包含您的函数。像这样:

var foo = function (val1 : string){
    // do something
    return {
        k1: 22,
        k2: 33
    };
}

您还可以让它实现一个接口,以便您知道返回的对象会发生什么。

interface IFoo {
    (val1: string): INumbers;
}
interface INumbers {
    k1 : number;
    k2 : number;
}
var foo : IFoo = (val1 : string){
    // do something
    return {
        k1: 22,
        k2: 33
    };
}

如果你真的,真的想要一个输出参数,即使你可以返回一个对象或数组(作为一个临时的元组对象(,看看foo和foo的调用站点......

function p(s) {
  document.body.appendChild(document.createTextNode(s));
  document.body.appendChild(document.createElement('BR'));
}
function foo(output: any): void {
  output.uno = 1;
  output.dos = 2;
}
var o: any = {};
function foo(o);
p(o.uno + " " + o.dos);

如果要维护类似 C# 的语法,可以使用:

function func(val1, k1, k2)
{
    k1.v = 7;
    k2.v = 9;
    return "";
}

并称它为">

func("", {}, {});   

有时参数未定义,您需要在方法中实例化它。在这种情况下,您可以使用"lambda 函数"或"箭头函数"并使用以下方式模拟输出参数:

例:

class classA
{
   propertyA : number;
   constructor(value: number){
        propertyA = number;
   }
}
class classB {
    // ...
    exampleMethod(){
       let classAInstance: classA;
       this.sumValueMethod((p) => classAInstance = p, 10);
       if(classAInstance != undefined)
           alert("Yeah"); 
    }
    sumValueMethod(paramA:(p: classA) => any, paramB: number){
       let variableA: classA = new classA(0);
       variableA.propertyA += paramB;
       paramA(variableA);
    }
}

我仍然不知道 2023 年 Typescript 中的输出参数。

我想补充一点,通常使用方法或将返回值解构为组件会更优雅。

假设,我们有

function foo(out x, out y, z) {
    x = z.x
    y = z.y
}

通常,输出参数与操作或彼此相关,将它们分组并封装在对象中是有意义的。

class Foo {
    var x; var y;
    foo(z) {
        x = z.x
        y = z.y
    }
}

但请注意,您不要忘记bind作为回调传递的函数。

function foo(z) {
    return [z.x, z.y]
}

以便您可以使用

[x, y] = foo(z)

这两种方法在表达式上基本上等效于使用输出参数。如果要将输出参数应用为参数,则可能不太方便。在这种情况下,需要 lambda 表达式或方法定义。

干杯!

最新更新