有没有办法为JSX中呈现的组件指定类型参数?
例如,考虑以下组件:
interface SelectorProps<T> {
selection: T;
options: T[];
}
class Selector<T> extends React.Component<SelectorProps<T>, {}> {
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试在JSX中呈现此组件:
<Selector selection="a" options={["a", "b", "c"]} />
Run Code Online (Sandbox Code Playgroud)
我收到这些错误:
TS2322:类型'string'不能分配给'T'类型.
TS2322:类型'string []'不能分配给'T []'.类型'string'不能分配给'T'类型.
我希望T被推断为string,否则一些方法来指定T=string在<Selector>.有解决方案吗?
我发现的唯一解决方法是扩展组件以消除所有类型参数:
class StringSelector extends Selector<string> { }
Run Code Online (Sandbox Code Playgroud) 我有一个目前用ES6编写的React项目,我正在迁移到TypeScript.我的import陈述有问题.
目前使用ES6,我使用NPM,ex安装了React依赖项npm install react,并使用Babel和Browserify构建输出ES5包.(使用Browserify不是必需的,我只是想让TS使用该项目.)
典型的React ES6文件如下所示:
import React from "react"
import {Router, Route, Link} from "react-router"
import Button from "./components/Button"
export default class App extends React.Component {
render(){
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
搬进TS,我已经安装了d.ts文件用我所有阵营的依赖tsd install react/,设置TSC module: "commonjs"和jsx: "react",从转换的几个文件*.jsx来*.tsx,我也得到这些编译的错误import语句:
错误:(1,8)TS1192:模块'"react"'没有默认导出.
该import Button声明没有错误.似乎TSC无法解析NPM模块依赖性.
我怎样才能让它发挥作用?
我有一个类似工厂的函数,用于返回一个子类实例BaseApi.它目前看起来像这样(修剪掉不相关的部分):
function getApi<T extends BaseApi>(apiClass: typeof BaseApi): T {
return new apiClass();
}
Run Code Online (Sandbox Code Playgroud)
我这样使用它:
const someApi = getApi<SomeApi>(SomeApi);
Run Code Online (Sandbox Code Playgroud)
这是有效的,但我想<SomeApi>通过我传递SomeApi构造函数的事实来推断.如果我省略<SomeApi>那么someApi推断是类型BaseApi,而不是SomeApi.更糟糕的是,实际上没有编译器相关性,<T extends BaseApi>并且typeof BaseApi是同一个东西,所以你可能会错误地做一些getApi<SecondApi>(FirstApi)没有编译器错误的事情.
所以我尝试定义apiClass为typeof T:
function getApi<T extends BaseApi>(apiClass: typeof T): T {
return new apiClass();
}
Run Code Online (Sandbox Code Playgroud)
我发现TS不明白这种用法T.有没有办法做到这一点?
我正在使用React TestUtil.renderIntoDocument来测试React组件类,就像这样(只使用TypeScript而不是Babel):
describe("MyComponent", () => {
it("will test something after being mounted", () => {
var component = TestUtils.renderIntoDocument(<MyComponent />);
// some test...
})
})
Run Code Online (Sandbox Code Playgroud)
这有效,但我想编写一个测试,验证其componentWillUnmount行为符合预期.但是,似乎测试运行器从未卸载组件,这并不奇怪.所以我的问题是:如何在测试中卸载组件?该TestUtil不会有什么看起来像什么,我想,沿着线的东西removeFromDocument我会想象.
我一直在关注mediawiki.org的一些教程,但我没有做到.我需要在我的所有wiki中添加一个新的CSS或JS代码(主要是因为我需要添加一些div标签).
你们能帮助我吗?
感谢.
为什么以下断言有效:
interface AllRequired {
a: string;
b: string;
}
let all = {a: "foo"} as AllRequired; // No error
Run Code Online (Sandbox Code Playgroud)
但是这个断言给出了一个错误:
interface SomeOptional {
a?: string;
b: string;
}
let some = {a: "foo"} as SomeOptional; // Error: Property 'b' missing
Run Code Online (Sandbox Code Playgroud)
我能看到的唯一区别是使其中一个接口属性为optional(?).似乎所有属性都不是可选的,我可以断言接口的部分对象,但只要任何接口属性是可选的,我就不能断言部分对象了.这对我来说没有意义,我一直无法找到这种行为的解释.这里发生了什么?
对于上下文:我在尝试解决React 采用部分状态对象的问题时遇到了这种行为setState(),但是TypeScript还没有部分类型来使这个状态接口正常工作.作为一种变通方法,我想出了setState({a: "a"} as MyState),发现这个工程只要接口MyState字段是所有非可选,但一旦失败,一些属性是可选的.(使所有属性都是可选的是一种解决方法,但在我的情况下非常不受欢迎.)
我以为我理解了新的TS 2.1 Pick类型的目的,但后来我看到它是如何在React类型定义中使用的,我不明白:
declare class Component<S> {
setState<K extends keyof S>(state: Pick<S, K>, callback?: () => any): void;
state: Readonly<S>;
}
Run Code Online (Sandbox Code Playgroud)
这允许你这样做:
interface PersonProps {
name: string;
age: number;
}
class Person extends Component<{}, PersonProps> {
test() {
this.setState({ age: 123 });
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我的困惑是,keyof S是{ name, age },但我打电话setState(),只有age-为什么没有抱怨缺少的name?
我的第一个想法是因为Pick是索引类型,它根本不需要存在所有键.说得通.但是,如果我尝试直接分配类型:
const ageState: Pick<PersonProps, keyof PersonProps> = { age: 123 };
Run Code Online (Sandbox Code Playgroud)
它确实抱怨丢失的 …
我有一个名为的组件Header,它存在于所有路由中,而应用程序的其余部分则发生变化。为了实现这一点,我的主要渲染代码如下所示(使用 ES6):
render(){
return (
<div>
<Header></Header>
<Router>
<Route path="/" component={Home} />
<Route path="/details/:id" component={Details} />
</Router>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
挑战在于,<Header>应该根据路线略有不同,例如每条路线都有一个唯一的标题。
如何才能实现这一目标?
我将 Gulp 与 Browserify 一起使用,并将 Babelify 用于 ES6 和 JSX-React 转译。尽管网上有很多例子,但我无法弄清楚如何生成指向原始预编译 ES6/JSX 文件的源映射。
这是我当前的 gulp browserify 任务,它基于此示例:
gulp.task('browserify', function() {
browserify({ entries: './src/js/main.jsx', extensions: ['.jsx'], debug: true })
.transform(babelify, {presets: ["es2015", "react"]})
.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist/js'));
});
Run Code Online (Sandbox Code Playgroud)
所有这些都是创建一个main.js.map文件,该文件似乎与捆绑main.js文件具有完全相同的内容。在 Chrome 中,它看起来像这样:
但我想调试原始源代码.jsx和.js(使用 ES6 语法)文件。它们在我的 IDE 中看起来像这样:
我怎样才能做到这一点?
我正在将Angular 1.5项目转换为TypeScript并遇到导入问题angularTranslate.
我尝试导入两个angular并angular-translate像这样:
import * as angular from "angular";
import * as angularTranslate from "angular-translate";
console.log(angular, angularTranslate);
Run Code Online (Sandbox Code Playgroud)
我正在使用安装的打字机DefinitelyTyped/angular-translate.d.ts.
当我使用TypeScript 1.8(module: "commonjs")进行编译时,它会发出以下JavaScript:
"use strict";
var angular = require("angular");
console.log(angular, angularTranslate);
Run Code Online (Sandbox Code Playgroud)
正如您所看到的那样,angularTranslate即使它被引用,它也已经删除了导入,并且angular保留了类似使用的导入.这会导致运行时错误ReferenceError: angularTranslate is not defined.这对巴别塔很好用.我该怎么导入angularTranslate?
编辑:
这也没有发现:
import angularTranslate = require("angular-translate");
Run Code Online (Sandbox Code Playgroud)
但这会发出预期的输出:
let angularTranslate = require("angular-translate");
Run Code Online (Sandbox Code Playgroud)
angular-translate模块是否有问题导致无法import在TypeScript中使用?
reactjs ×6
typescript ×6
angularjs ×1
babeljs ×1
browserify ×1
css ×1
ecmascript-6 ×1
generics ×1
gulp ×1
html ×1
jestjs ×1
mediawiki ×1
react-jsx ×1
react-router ×1
source-maps ×1